2 * Copyright © 2016-2017 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
25 #include <linux/bitfield.h>
26 #include <linux/firmware.h>
27 #include <drm/drm_print.h>
29 #include "intel_uc_fw.h"
33 * List of required GuC and HuC binaries per-platform.
34 * Must be ordered based on platform + revid, from newer to older.
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))
44 #define __MAKE_UC_FW_PATH(prefix_, name_, separator_, major_, minor_, patch_) \
46 __stringify(prefix_) name_ \
47 __stringify(major_) separator_ \
48 __stringify(minor_) separator_ \
49 __stringify(patch_) ".bin"
51 #define MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_) \
52 __MAKE_UC_FW_PATH(prefix_, "_guc_", ".", major_, minor_, patch_)
54 #define MAKE_HUC_FW_PATH(prefix_, major_, minor_, bld_num_) \
55 __MAKE_UC_FW_PATH(prefix_, "_huc_ver", "_", major_, minor_, bld_num_)
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_);
62 INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
64 /* The below structs and macros are used to iterate across the list of blobs */
65 struct __packed uc_fw_blob {
71 #define UC_FW_BLOB(major_, minor_, path_) \
72 { .major = major_, .minor = minor_, .path = path_ }
74 #define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
75 UC_FW_BLOB(major_, minor_, \
76 MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_))
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_))
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];
88 #define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
90 .p = INTEL_##platform_, \
92 .blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
93 .blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
97 __uc_fw_auto_select(struct intel_uc_fw *uc_fw, enum intel_platform p, u8 rev)
99 static const struct uc_fw_platform_requirement fw_blobs[] = {
100 INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
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;
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)
121 if (fw_blobs[i].p == fw_blobs[i - 1].p &&
122 fw_blobs[i].rev < fw_blobs[i - 1].rev)
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),
128 intel_platform_name(fw_blobs[i].p),
137 __uc_fw_override(struct intel_uc_fw *uc_fw)
139 switch (uc_fw->type) {
140 case INTEL_UC_FW_TYPE_GUC:
141 uc_fw->path = i915_modparams.guc_firmware_path;
143 case INTEL_UC_FW_TYPE_HUC:
144 uc_fw->path = i915_modparams.huc_firmware_path;
152 * intel_uc_fw_init_early - initialize the uC object and select the firmware
153 * @i915: device private
154 * @uc_fw: uC firmware
157 * Initialize the state of our uC object and relevant tracking and select the
158 * firmware to fetch and load.
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)
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
168 BUILD_BUG_ON(INTEL_UC_FIRMWARE_UNINITIALIZED);
169 GEM_BUG_ON(uc_fw->status);
170 GEM_BUG_ON(uc_fw->path);
174 if (HAS_GT_UC(i915) && likely(!__uc_fw_override(uc_fw)))
175 __uc_fw_auto_select(uc_fw, INTEL_INFO(i915)->platform,
179 uc_fw->status = INTEL_UC_FIRMWARE_SELECTED;
181 uc_fw->status = INTEL_UC_FIRMWARE_NOT_SUPPORTED;
185 * intel_uc_fw_fetch - fetch uC firmware
187 * @dev_priv: device private
188 * @uc_fw: uC firmware
190 * Fetch uC firmware into GEM obj.
192 void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
193 struct intel_uc_fw *uc_fw)
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;
202 GEM_BUG_ON(!intel_uc_fw_supported(uc_fw));
204 err = request_firmware(&fw, uc_fw->path, &pdev->dev);
208 DRM_DEBUG_DRIVER("%s fw size %zu ptr %p\n",
209 intel_uc_fw_type_repr(uc_fw->type), fw->size, fw);
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));
220 css = (struct uc_css_header *)fw->data;
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) *
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));
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);
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);
246 uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
247 uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
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);
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,
263 uc_fw->minor_ver_found = FIELD_GET(CSS_SW_VERSION_GUC_MINOR,
267 case INTEL_UC_FW_TYPE_HUC:
268 uc_fw->major_ver_found = FIELD_GET(CSS_SW_VERSION_HUC_MAJOR,
270 uc_fw->minor_ver_found = FIELD_GET(CSS_SW_VERSION_HUC_MINOR,
275 MISSING_CASE(uc_fw->type);
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);
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);
297 obj = i915_gem_object_create_shmem_from_data(dev_priv,
301 DRM_DEBUG_DRIVER("%s fw object_create err=%d\n",
302 intel_uc_fw_type_repr(uc_fw->type), err);
307 uc_fw->size = fw->size;
308 uc_fw->status = INTEL_UC_FIRMWARE_AVAILABLE;
310 release_firmware(fw);
314 uc_fw->status = INTEL_UC_FIRMWARE_MISSING;
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);
321 release_firmware(fw); /* OK even if fw is NULL */
324 static void intel_uc_fw_ggtt_bind(struct intel_uc_fw *uc_fw)
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,
335 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
336 GEM_BUG_ON(dummy.node.size > ggtt->uc_fw.size);
338 /* uc_fw->obj cache domains were not controlled across suspend */
339 drm_clflush_sg(dummy.pages);
341 ggtt->vm.insert_entries(&ggtt->vm, &dummy, I915_CACHE_NONE, 0);
344 static void intel_uc_fw_ggtt_unbind(struct intel_uc_fw *uc_fw)
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);
350 ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size);
354 * intel_uc_fw_upload - load uC firmware using custom loader
355 * @uc_fw: uC firmware
356 * @xfer: custom uC firmware loader function
358 * Loads uC firmware using custom loader and updates internal flags.
360 * Return: 0 on success, non-zero on failure.
362 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
363 int (*xfer)(struct intel_uc_fw *uc_fw))
367 DRM_DEBUG_DRIVER("%s fw load %s\n",
368 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path);
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));
373 if (!intel_uc_fw_is_available(uc_fw))
375 /* Call custom loader */
376 intel_uc_fw_ggtt_bind(uc_fw);
378 intel_uc_fw_ggtt_unbind(uc_fw);
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));
386 DRM_INFO("%s: Loaded firmware %s (version %u.%u)\n",
387 intel_uc_fw_type_repr(uc_fw->type),
389 uc_fw->major_ver_found, uc_fw->minor_ver_found);
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));
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);
404 int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
408 /* this should happen before the load! */
409 GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
411 if (!intel_uc_fw_is_available(uc_fw))
414 err = i915_gem_object_pin_pages(uc_fw->obj);
416 DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",
417 intel_uc_fw_type_repr(uc_fw->type), err);
422 void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
424 if (!intel_uc_fw_is_available(uc_fw))
427 i915_gem_object_unpin_pages(uc_fw->obj);
430 u32 intel_uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
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;
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));
440 return lower_32_bits(node->start);
444 * intel_uc_fw_cleanup_fetch - cleanup uC firmware
446 * @uc_fw: uC firmware
448 * Cleans up uC firmware by releasing the firmware GEM obj.
450 void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw)
452 struct drm_i915_gem_object *obj;
454 obj = fetch_and_zero(&uc_fw->obj);
456 i915_gem_object_put(obj);
458 uc_fw->status = INTEL_UC_FIRMWARE_SELECTED;
462 * intel_uc_fw_dump - dump information about uC firmware
463 * @uc_fw: uC firmware
464 * @p: the &drm_printer
466 * Pretty printer for uC firmware.
468 void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p)
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);