Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: MIT */
0002 /*
0003  * Copyright © 2014-2019 Intel Corporation
0004  */
0005 
0006 #ifndef _INTEL_UC_FW_H_
0007 #define _INTEL_UC_FW_H_
0008 
0009 #include <linux/types.h>
0010 #include "intel_uc_fw_abi.h"
0011 #include "intel_device_info.h"
0012 #include "i915_gem.h"
0013 #include "i915_vma.h"
0014 
0015 struct drm_printer;
0016 struct drm_i915_private;
0017 struct intel_gt;
0018 
0019 /* Home of GuC, HuC and DMC firmwares */
0020 #define INTEL_UC_FIRMWARE_URL "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/i915"
0021 
0022 /*
0023  * +------------+---------------------------------------------------+
0024  * |   PHASE    |           FIRMWARE STATUS TRANSITIONS             |
0025  * +============+===================================================+
0026  * |            |               UNINITIALIZED                       |
0027  * +------------+-               /   |   \                         -+
0028  * |            |   DISABLED <--/    |    \--> NOT_SUPPORTED        |
0029  * | init_early |                    V                              |
0030  * |            |                 SELECTED                          |
0031  * +------------+-               /   |   \                         -+
0032  * |            |    MISSING <--/    |    \--> ERROR                |
0033  * |   fetch    |                    V                              |
0034  * |            |                 AVAILABLE                         |
0035  * +------------+-                   |   \                         -+
0036  * |            |                    |    \--> INIT FAIL            |
0037  * |   init     |                    V                              |
0038  * |            |        /------> LOADABLE <----<-----------\       |
0039  * +------------+-       \         /    \        \           \     -+
0040  * |            |    LOAD FAIL <--<      \--> TRANSFERRED     \     |
0041  * |   upload   |                  \           /   \          /     |
0042  * |            |                   \---------/     \--> RUNNING    |
0043  * +------------+---------------------------------------------------+
0044  */
0045 
0046 enum intel_uc_fw_status {
0047     INTEL_UC_FIRMWARE_NOT_SUPPORTED = -1, /* no uc HW */
0048     INTEL_UC_FIRMWARE_UNINITIALIZED = 0, /* used to catch checks done too early */
0049     INTEL_UC_FIRMWARE_DISABLED, /* disabled */
0050     INTEL_UC_FIRMWARE_SELECTED, /* selected the blob we want to load */
0051     INTEL_UC_FIRMWARE_MISSING, /* blob not found on the system */
0052     INTEL_UC_FIRMWARE_ERROR, /* invalid format or version */
0053     INTEL_UC_FIRMWARE_AVAILABLE, /* blob found and copied in mem */
0054     INTEL_UC_FIRMWARE_INIT_FAIL, /* failed to prepare fw objects for load */
0055     INTEL_UC_FIRMWARE_LOADABLE, /* all fw-required objects are ready */
0056     INTEL_UC_FIRMWARE_LOAD_FAIL, /* failed to xfer or init/auth the fw */
0057     INTEL_UC_FIRMWARE_TRANSFERRED, /* dma xfer done */
0058     INTEL_UC_FIRMWARE_RUNNING /* init/auth done */
0059 };
0060 
0061 enum intel_uc_fw_type {
0062     INTEL_UC_FW_TYPE_GUC = 0,
0063     INTEL_UC_FW_TYPE_HUC
0064 };
0065 #define INTEL_UC_FW_NUM_TYPES 2
0066 
0067 /*
0068  * This structure encapsulates all the data needed during the process
0069  * of fetching, caching, and loading the firmware image into the uC.
0070  */
0071 struct intel_uc_fw {
0072     enum intel_uc_fw_type type;
0073     union {
0074         const enum intel_uc_fw_status status;
0075         enum intel_uc_fw_status __status; /* no accidental overwrites */
0076     };
0077     const char *wanted_path;
0078     const char *path;
0079     bool user_overridden;
0080     size_t size;
0081     struct drm_i915_gem_object *obj;
0082     /**
0083      * @dummy: A vma used in binding the uc fw to ggtt. We can't define this
0084      * vma on the stack as it can lead to a stack overflow, so we define it
0085      * here. Safe to have 1 copy per uc fw because the binding is single
0086      * threaded as it done during driver load (inherently single threaded)
0087      * or during a GT reset (mutex guarantees single threaded).
0088      */
0089     struct i915_vma_resource dummy;
0090     struct i915_vma *rsa_data;
0091 
0092     /*
0093      * The firmware build process will generate a version header file with major and
0094      * minor version defined. The versions are built into CSS header of firmware.
0095      * i915 kernel driver set the minimal firmware version required per platform.
0096      */
0097     u16 major_ver_wanted;
0098     u16 minor_ver_wanted;
0099     u16 major_ver_found;
0100     u16 minor_ver_found;
0101 
0102     struct {
0103         const char *path;
0104         u16 major_ver;
0105         u16 minor_ver;
0106     } fallback;
0107 
0108     u32 rsa_size;
0109     u32 ucode_size;
0110 
0111     u32 private_data_size;
0112 
0113     bool loaded_via_gsc;
0114 };
0115 
0116 #ifdef CONFIG_DRM_I915_DEBUG_GUC
0117 void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
0118                    enum intel_uc_fw_status status);
0119 #else
0120 static inline void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
0121                          enum intel_uc_fw_status status)
0122 {
0123     uc_fw->__status = status;
0124 }
0125 #endif
0126 
0127 static inline
0128 const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
0129 {
0130     switch (status) {
0131     case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
0132         return "N/A";
0133     case INTEL_UC_FIRMWARE_UNINITIALIZED:
0134         return "UNINITIALIZED";
0135     case INTEL_UC_FIRMWARE_DISABLED:
0136         return "DISABLED";
0137     case INTEL_UC_FIRMWARE_SELECTED:
0138         return "SELECTED";
0139     case INTEL_UC_FIRMWARE_MISSING:
0140         return "MISSING";
0141     case INTEL_UC_FIRMWARE_ERROR:
0142         return "ERROR";
0143     case INTEL_UC_FIRMWARE_AVAILABLE:
0144         return "AVAILABLE";
0145     case INTEL_UC_FIRMWARE_INIT_FAIL:
0146         return "INIT FAIL";
0147     case INTEL_UC_FIRMWARE_LOADABLE:
0148         return "LOADABLE";
0149     case INTEL_UC_FIRMWARE_LOAD_FAIL:
0150         return "LOAD FAIL";
0151     case INTEL_UC_FIRMWARE_TRANSFERRED:
0152         return "TRANSFERRED";
0153     case INTEL_UC_FIRMWARE_RUNNING:
0154         return "RUNNING";
0155     }
0156     return "<invalid>";
0157 }
0158 
0159 static inline int intel_uc_fw_status_to_error(enum intel_uc_fw_status status)
0160 {
0161     switch (status) {
0162     case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
0163         return -ENODEV;
0164     case INTEL_UC_FIRMWARE_UNINITIALIZED:
0165         return -EACCES;
0166     case INTEL_UC_FIRMWARE_DISABLED:
0167         return -EPERM;
0168     case INTEL_UC_FIRMWARE_MISSING:
0169         return -ENOENT;
0170     case INTEL_UC_FIRMWARE_ERROR:
0171         return -ENOEXEC;
0172     case INTEL_UC_FIRMWARE_INIT_FAIL:
0173     case INTEL_UC_FIRMWARE_LOAD_FAIL:
0174         return -EIO;
0175     case INTEL_UC_FIRMWARE_SELECTED:
0176         return -ESTALE;
0177     case INTEL_UC_FIRMWARE_AVAILABLE:
0178     case INTEL_UC_FIRMWARE_LOADABLE:
0179     case INTEL_UC_FIRMWARE_TRANSFERRED:
0180     case INTEL_UC_FIRMWARE_RUNNING:
0181         return 0;
0182     }
0183     return -EINVAL;
0184 }
0185 
0186 static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type)
0187 {
0188     switch (type) {
0189     case INTEL_UC_FW_TYPE_GUC:
0190         return "GuC";
0191     case INTEL_UC_FW_TYPE_HUC:
0192         return "HuC";
0193     }
0194     return "uC";
0195 }
0196 
0197 static inline enum intel_uc_fw_status
0198 __intel_uc_fw_status(struct intel_uc_fw *uc_fw)
0199 {
0200     /* shouldn't call this before checking hw/blob availability */
0201     GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED);
0202     return uc_fw->status;
0203 }
0204 
0205 static inline bool intel_uc_fw_is_supported(struct intel_uc_fw *uc_fw)
0206 {
0207     return __intel_uc_fw_status(uc_fw) != INTEL_UC_FIRMWARE_NOT_SUPPORTED;
0208 }
0209 
0210 static inline bool intel_uc_fw_is_enabled(struct intel_uc_fw *uc_fw)
0211 {
0212     return __intel_uc_fw_status(uc_fw) > INTEL_UC_FIRMWARE_DISABLED;
0213 }
0214 
0215 static inline bool intel_uc_fw_is_available(struct intel_uc_fw *uc_fw)
0216 {
0217     return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_AVAILABLE;
0218 }
0219 
0220 static inline bool intel_uc_fw_is_loadable(struct intel_uc_fw *uc_fw)
0221 {
0222     return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_LOADABLE;
0223 }
0224 
0225 static inline bool intel_uc_fw_is_loaded(struct intel_uc_fw *uc_fw)
0226 {
0227     return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_TRANSFERRED;
0228 }
0229 
0230 static inline bool intel_uc_fw_is_running(struct intel_uc_fw *uc_fw)
0231 {
0232     return __intel_uc_fw_status(uc_fw) == INTEL_UC_FIRMWARE_RUNNING;
0233 }
0234 
0235 static inline bool intel_uc_fw_is_overridden(const struct intel_uc_fw *uc_fw)
0236 {
0237     return uc_fw->user_overridden;
0238 }
0239 
0240 static inline void intel_uc_fw_sanitize(struct intel_uc_fw *uc_fw)
0241 {
0242     if (intel_uc_fw_is_loaded(uc_fw))
0243         intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_LOADABLE);
0244 }
0245 
0246 static inline u32 __intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
0247 {
0248     return sizeof(struct uc_css_header) + uc_fw->ucode_size;
0249 }
0250 
0251 /**
0252  * intel_uc_fw_get_upload_size() - Get size of firmware needed to be uploaded.
0253  * @uc_fw: uC firmware.
0254  *
0255  * Get the size of the firmware and header that will be uploaded to WOPCM.
0256  *
0257  * Return: Upload firmware size, or zero on firmware fetch failure.
0258  */
0259 static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
0260 {
0261     if (!intel_uc_fw_is_available(uc_fw))
0262         return 0;
0263 
0264     return __intel_uc_fw_get_upload_size(uc_fw);
0265 }
0266 
0267 void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
0268                 enum intel_uc_fw_type type);
0269 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw);
0270 void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw);
0271 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32 dma_flags);
0272 int intel_uc_fw_init(struct intel_uc_fw *uc_fw);
0273 void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
0274 size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len);
0275 void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p);
0276 
0277 #endif