[Intel-gfx] [PATCH 2/9] drm/i915: Move uC fw helper code into dedicated files

Michal Wajdeczko michal.wajdeczko at intel.com
Sat Sep 30 15:50:42 UTC 2017


On Sat, 30 Sep 2017 16:43:35 +0200, Sagar Arun Kamble  
<sagar.a.kamble at intel.com> wrote:

>
>
> On 9/30/2017 3:31 PM, Sagar Arun Kamble wrote:
>>
>>
>> On 9/29/2017 11:11 PM, Michal Wajdeczko wrote:
>>> This is a prerequisite to unblock next steps.
>>> No functional changes, only s/dev_priv/i915
>>>
>>> Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
>>> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
>>> Cc: Chris Wilson <chris at chris-wilson.co.uk>
>>> Cc: Sagar Arun Kamble <sagar.a.kamble at intel.com>
>> Reviewed-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
> Just realized that uC specific uc_css_header declaration is still  
> present in intel_guc_fwif.h. is it good idea to pull this to  
> intel_uc_fw.h?

I was thinking about the same, but since "uc_css_header" is part of
the GuC FW API and we keep all such shared data types in fwif.h file
(like guc_stage_desc and others) I wasn't sure that will be accepted.

But we can try do this later as part of unifying code with DMC (where
similar intel_css_header is defined)

Michal


>>> ---
>>>   drivers/gpu/drm/i915/Makefile      |   1 +
>>>   drivers/gpu/drm/i915/intel_uc.c    | 163  
>>> ++--------------------------------
>>>   drivers/gpu/drm/i915/intel_uc.h    |  67 +-------------
>>>   drivers/gpu/drm/i915/intel_uc_fw.c | 177  
>>> +++++++++++++++++++++++++++++++++++++
>>>   drivers/gpu/drm/i915/intel_uc_fw.h |  95 ++++++++++++++++++++
>>>   5 files changed, 280 insertions(+), 223 deletions(-)
>>>   create mode 100644 drivers/gpu/drm/i915/intel_uc_fw.c
>>>   create mode 100644 drivers/gpu/drm/i915/intel_uc_fw.h
>>>
>>> diff --git a/drivers/gpu/drm/i915/Makefile  
>>> b/drivers/gpu/drm/i915/Makefile
>>> index 5182e3d..4850f26 100644
>>> --- a/drivers/gpu/drm/i915/Makefile
>>> +++ b/drivers/gpu/drm/i915/Makefile
>>> @@ -59,6 +59,7 @@ i915-y += i915_cmd_parser.o \
>>>     # general-purpose microcontroller (GuC) support
>>>   i915-y += intel_uc.o \
>>> +      intel_uc_fw.o \
>>>         intel_guc_ct.o \
>>>         intel_guc_log.o \
>>>         intel_guc_loader.o \
>>> diff --git a/drivers/gpu/drm/i915/intel_uc.c  
>>> b/drivers/gpu/drm/i915/intel_uc.c
>>> index 2774778..9426cc1 100644
>>> --- a/drivers/gpu/drm/i915/intel_uc.c
>>> +++ b/drivers/gpu/drm/i915/intel_uc.c
>>> @@ -26,19 +26,6 @@
>>>   #include "intel_uc.h"
>>>   #include <linux/firmware.h>
>>>   -/* Cleans up uC firmware by releasing the firmware GEM obj.
>>> - */
>>> -static void __intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
>>> -{
>>> -    struct drm_i915_gem_object *obj;
>>> -
>>> -    obj = fetch_and_zero(&uc_fw->obj);
>>> -    if (obj)
>>> -        i915_gem_object_put(obj);
>>> -
>>> -    uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>>> -}
>>> -
>>>   /* Reset GuC providing us with fresh state for both GuC and HuC.
>>>    */
>>>   static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
>>> @@ -112,154 +99,16 @@ void intel_uc_init_early(struct drm_i915_private  
>>> *dev_priv)
>>>       guc->notify = gen8_guc_raise_irq;
>>>   }
>>>   -static void fetch_uc_fw(struct drm_i915_private *dev_priv,
>>> -            struct intel_uc_fw *uc_fw)
>>> -{
>>> -    struct pci_dev *pdev = dev_priv->drm.pdev;
>>> -    struct drm_i915_gem_object *obj;
>>> -    const struct firmware *fw = NULL;
>>> -    struct uc_css_header *css;
>>> -    size_t size;
>>> -    int err;
>>> -
>>> -    if (!uc_fw->path)
>>> -        return;
>>> -
>>> -    uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
>>> -
>>> -    DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status  
>>> %s\n",
>>> -             intel_uc_fw_status_repr(uc_fw->fetch_status));
>>> -
>>> -    err = request_firmware(&fw, uc_fw->path, &pdev->dev);
>>> -    if (err)
>>> -        goto fail;
>>> -    if (!fw)
>>> -        goto fail;
>>> -
>>> -    DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
>>> -             uc_fw->path, fw);
>>> -
>>> -    /* Check the size of the blob before examining buffer contents */
>>> -    if (fw->size < sizeof(struct uc_css_header)) {
>>> -        DRM_NOTE("Firmware header is missing\n");
>>> -        goto fail;
>>> -    }
>>> -
>>> -    css = (struct uc_css_header *)fw->data;
>>> -
>>> -    /* Firmware bits always start from header */
>>> -    uc_fw->header_offset = 0;
>>> -    uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>>> -                  css->key_size_dw - css->exponent_size_dw) *  
>>> sizeof(u32);
>>> -
>>> -    if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>>> -        DRM_NOTE("CSS header definition mismatch\n");
>>> -        goto fail;
>>> -    }
>>> -
>>> -    /* then, uCode */
>>> -    uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
>>> -    uc_fw->ucode_size = (css->size_dw - css->header_size_dw) *  
>>> sizeof(u32);
>>> -
>>> -    /* now RSA */
>>> -    if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
>>> -        DRM_NOTE("RSA key size is bad\n");
>>> -        goto fail;
>>> -    }
>>> -    uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
>>> -    uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
>>> -
>>> -    /* At least, it should have header, uCode and RSA. Size of all  
>>> three. */
>>> -    size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
>>> -    if (fw->size < size) {
>>> -        DRM_NOTE("Missing firmware components\n");
>>> -        goto fail;
>>> -    }
>>> -
>>> -    /*
>>> -     * The GuC firmware image has the version number embedded at a
>>> -     * well-known offset within the firmware blob; note that major /  
>>> minor
>>> -     * version are TWO bytes each (i.e. u16), although all pointers  
>>> and
>>> -     * offsets are defined in terms of bytes (u8).
>>> -     */
>>> -    switch (uc_fw->type) {
>>> -    case INTEL_UC_FW_TYPE_GUC:
>>> -        /* Header and uCode will be loaded to WOPCM. Size of the two.  
>>> */
>>> -        size = uc_fw->header_size + uc_fw->ucode_size;
>>> -
>>> -        /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).  
>>> */
>>> -        if (size > intel_guc_wopcm_size(dev_priv)) {
>>> -            DRM_ERROR("Firmware is too large to fit in WOPCM\n");
>>> -            goto fail;
>>> -        }
>>> -        uc_fw->major_ver_found = css->guc.sw_version >> 16;
>>> -        uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
>>> -        break;
>>> -
>>> -    case INTEL_UC_FW_TYPE_HUC:
>>> -        uc_fw->major_ver_found = css->huc.sw_version >> 16;
>>> -        uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
>>> -        break;
>>> -
>>> -    default:
>>> -        DRM_ERROR("Unknown firmware type %d\n", uc_fw->type);
>>> -        err = -ENOEXEC;
>>> -        goto fail;
>>> -    }
>>> -
>>> -    if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0)  
>>> {
>>> -        DRM_NOTE("Skipping %s firmware version check\n",
>>> -             intel_uc_fw_type_repr(uc_fw->type));
>>> -    } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>>> -           uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
>>> -        DRM_NOTE("%s firmware version %d.%d, required %d.%d\n",
>>> -             intel_uc_fw_type_repr(uc_fw->type),
>>> -             uc_fw->major_ver_found, uc_fw->minor_ver_found,
>>> -             uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
>>> -        err = -ENOEXEC;
>>> -        goto fail;
>>> -    }
>>> -
>>> -    DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
>>> -             uc_fw->major_ver_found, uc_fw->minor_ver_found,
>>> -             uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
>>> -
>>> -    obj = i915_gem_object_create_from_data(dev_priv, fw->data,  
>>> fw->size);
>>> -    if (IS_ERR(obj)) {
>>> -        err = PTR_ERR(obj);
>>> -        goto fail;
>>> -    }
>>> -
>>> -    uc_fw->obj = obj;
>>> -    uc_fw->size = fw->size;
>>> -
>>> -    DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
>>> -             uc_fw->obj);
>>> -
>>> -    release_firmware(fw);
>>> -    uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
>>> -    return;
>>> -
>>> -fail:
>>> -    DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
>>> -         uc_fw->path, err);
>>> -    DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj  
>>> %p\n",
>>> -             err, fw, uc_fw->obj);
>>> -
>>> -    release_firmware(fw);        /* OK even if fw is NULL */
>>> -    uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
>>> -}
>>> -
>>> -void intel_uc_init_fw(struct drm_i915_private *dev_priv)
>>> +void intel_uc_init_fw(struct drm_i915_private *i915)
>>>   {
>>> -    fetch_uc_fw(dev_priv, &dev_priv->huc.fw);
>>> -    fetch_uc_fw(dev_priv, &dev_priv->guc.fw);
>>> +    i915_fetch_uc_fw(i915, &i915->huc.fw);
>>> +    i915_fetch_uc_fw(i915, &i915->guc.fw);
>>>   }
>>>   -void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
>>> +void intel_uc_fini_fw(struct drm_i915_private *i915)
>>>   {
>>> -    __intel_uc_fw_fini(&dev_priv->guc.fw);
>>> -    __intel_uc_fw_fini(&dev_priv->huc.fw);
>>> +    intel_uc_fw_fini(&i915->guc.fw);
>>> +    intel_uc_fw_fini(&i915->huc.fw);
>>>   }
>>>     static inline i915_reg_t guc_send_reg(struct intel_guc *guc, u32 i)
>>> diff --git a/drivers/gpu/drm/i915/intel_uc.h  
>>> b/drivers/gpu/drm/i915/intel_uc.h
>>> index 38ec880..d111f79 100644
>>> --- a/drivers/gpu/drm/i915/intel_uc.h
>>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>>> @@ -24,6 +24,7 @@
>>>   #ifndef _INTEL_UC_H_
>>>   #define _INTEL_UC_H_
>>>   +#include "intel_uc_fw.h"
>>>   #include "intel_guc_fwif.h"
>>>   #include "i915_guc_reg.h"
>>>   #include "intel_ringbuffer.h"
>>> @@ -70,72 +71,6 @@ struct i915_guc_client {
>>>       uint64_t submissions[I915_NUM_ENGINES];
>>>   };
>>>   -enum intel_uc_fw_status {
>>> -    INTEL_UC_FIRMWARE_FAIL = -1,
>>> -    INTEL_UC_FIRMWARE_NONE = 0,
>>> -    INTEL_UC_FIRMWARE_PENDING,
>>> -    INTEL_UC_FIRMWARE_SUCCESS
>>> -};
>>> -
>>> -/* User-friendly representation of an enum */
>>> -static inline
>>> -const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
>>> -{
>>> -    switch (status) {
>>> -    case INTEL_UC_FIRMWARE_FAIL:
>>> -        return "FAIL";
>>> -    case INTEL_UC_FIRMWARE_NONE:
>>> -        return "NONE";
>>> -    case INTEL_UC_FIRMWARE_PENDING:
>>> -        return "PENDING";
>>> -    case INTEL_UC_FIRMWARE_SUCCESS:
>>> -        return "SUCCESS";
>>> -    }
>>> -    return "<invalid>";
>>> -}
>>> -
>>> -enum intel_uc_fw_type {
>>> -    INTEL_UC_FW_TYPE_GUC,
>>> -    INTEL_UC_FW_TYPE_HUC
>>> -};
>>> -
>>> -/* User-friendly representation of an enum */
>>> -static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type  
>>> type)
>>> -{
>>> -    switch (type) {
>>> -    case INTEL_UC_FW_TYPE_GUC:
>>> -        return "GuC";
>>> -    case INTEL_UC_FW_TYPE_HUC:
>>> -        return "HuC";
>>> -    }
>>> -    return "uC";
>>> -}
>>> -
>>> -/*
>>> - * This structure encapsulates all the data needed during the process
>>> - * of fetching, caching, and loading the firmware image into the GuC.
>>> - */
>>> -struct intel_uc_fw {
>>> -    const char *path;
>>> -    size_t size;
>>> -    struct drm_i915_gem_object *obj;
>>> -    enum intel_uc_fw_status fetch_status;
>>> -    enum intel_uc_fw_status load_status;
>>> -
>>> -    uint16_t major_ver_wanted;
>>> -    uint16_t minor_ver_wanted;
>>> -    uint16_t major_ver_found;
>>> -    uint16_t minor_ver_found;
>>> -
>>> -    enum intel_uc_fw_type type;
>>> -    uint32_t header_size;
>>> -    uint32_t header_offset;
>>> -    uint32_t rsa_size;
>>> -    uint32_t rsa_offset;
>>> -    uint32_t ucode_size;
>>> -    uint32_t ucode_offset;
>>> -};
>>> -
>>>   struct intel_guc_log {
>>>       uint32_t flags;
>>>       struct i915_vma *vma;
>>> diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c  
>>> b/drivers/gpu/drm/i915/intel_uc_fw.c
>>> new file mode 100644
>>> index 0000000..29920af
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/i915/intel_uc_fw.c
>>> @@ -0,0 +1,177 @@
>>> +/*
>>> + * Copyright © 2016-2017 Intel Corporation
>>> + *
>>> + * Permission is hereby granted, free of charge, to any person  
>>> obtaining a
>>> + * copy of this software and associated documentation files (the  
>>> "Software"),
>>> + * to deal in the Software without restriction, including without  
>>> limitation
>>> + * the rights to use, copy, modify, merge, publish, distribute,  
>>> sublicense,
>>> + * and/or sell copies of the Software, and to permit persons to whom  
>>> the
>>> + * Software is furnished to do so, subject to the following  
>>> conditions:
>>> + *
>>> + * The above copyright notice and this permission notice (including  
>>> the next
>>> + * paragraph) shall be included in all copies or substantial portions  
>>> of the
>>> + * Software.
>>> + *
>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
>>> EXPRESS OR
>>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
>>> MERCHANTABILITY,
>>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  
>>> SHALL
>>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES  
>>> OR OTHER
>>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  
>>> ARISING
>>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
>>> OTHER DEALINGS
>>> + * IN THE SOFTWARE.
>>> + *
>>> + */
>>> +
>>> +#include <linux/firmware.h>
>>> +#include "i915_drv.h"
>>> +
>>> +/* Cleans up uC firmware by releasing the firmware GEM obj.
>>> + */
>>> +void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
>>> +{
>>> +    struct drm_i915_gem_object *obj;
>>> +
>>> +    obj = fetch_and_zero(&uc_fw->obj);
>>> +    if (obj)
>>> +        i915_gem_object_put(obj);
>>> +
>>> +    uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>>> +}
>>> +
>>> +void i915_fetch_uc_fw(struct drm_i915_private *i915,
>>> +              struct intel_uc_fw *uc_fw)
>>> +{
>>> +    struct pci_dev *pdev = i915->drm.pdev;
>>> +    struct drm_i915_gem_object *obj;
>>> +    const struct firmware *fw = NULL;
>>> +    struct uc_css_header *css;
>>> +    size_t size;
>>> +    int err;
>>> +
>>> +    if (!uc_fw->path)
>>> +        return;
>>> +
>>> +    uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
>>> +
>>> +    DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status  
>>> %s\n",
>>> +             intel_uc_fw_status_repr(uc_fw->fetch_status));
>>> +
>>> +    err = request_firmware(&fw, uc_fw->path, &pdev->dev);
>>> +    if (err)
>>> +        goto fail;
>>> +    if (!fw)
>>> +        goto fail;
>>> +
>>> +    DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
>>> +             uc_fw->path, fw);
>>> +
>>> +    /* Check the size of the blob before examining buffer contents */
>>> +    if (fw->size < sizeof(struct uc_css_header)) {
>>> +        DRM_NOTE("Firmware header is missing\n");
>>> +        goto fail;
>>> +    }
>>> +
>>> +    css = (struct uc_css_header *)fw->data;
>>> +
>>> +    /* Firmware bits always start from header */
>>> +    uc_fw->header_offset = 0;
>>> +    uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>>> +                  css->key_size_dw - css->exponent_size_dw) *  
>>> sizeof(u32);
>>> +
>>> +    if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>>> +        DRM_NOTE("CSS header definition mismatch\n");
>>> +        goto fail;
>>> +    }
>>> +
>>> +    /* then, uCode */
>>> +    uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
>>> +    uc_fw->ucode_size = (css->size_dw - css->header_size_dw) *  
>>> sizeof(u32);
>>> +
>>> +    /* now RSA */
>>> +    if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
>>> +        DRM_NOTE("RSA key size is bad\n");
>>> +        goto fail;
>>> +    }
>>> +    uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
>>> +    uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
>>> +
>>> +    /* At least, it should have header, uCode and RSA. Size of all  
>>> three. */
>>> +    size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
>>> +    if (fw->size < size) {
>>> +        DRM_NOTE("Missing firmware components\n");
>>> +        goto fail;
>>> +    }
>>> +
>>> +    /*
>>> +     * The GuC firmware image has the version number embedded at a
>>> +     * well-known offset within the firmware blob; note that major /  
>>> minor
>>> +     * version are TWO bytes each (i.e. u16), although all pointers  
>>> and
>>> +     * offsets are defined in terms of bytes (u8).
>>> +     */
>>> +    switch (uc_fw->type) {
>>> +    case INTEL_UC_FW_TYPE_GUC:
>>> +        /* Header and uCode will be loaded to WOPCM. Size of the two.  
>>> */
>>> +        size = uc_fw->header_size + uc_fw->ucode_size;
>>> +
>>> +        /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).  
>>> */
>>> +        if (size > intel_guc_wopcm_size(i915)) {
>>> +            DRM_ERROR("Firmware is too large to fit in WOPCM\n");
>>> +            goto fail;
>>> +        }
>>> +        uc_fw->major_ver_found = css->guc.sw_version >> 16;
>>> +        uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
>>> +        break;
>>> +
>>> +    case INTEL_UC_FW_TYPE_HUC:
>>> +        uc_fw->major_ver_found = css->huc.sw_version >> 16;
>>> +        uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
>>> +        break;
>>> +
>>> +    default:
>>> +        DRM_ERROR("Unknown firmware type %d\n", uc_fw->type);
>>> +        err = -ENOEXEC;
>>> +        goto fail;
>>> +    }
>>> +
>>> +    if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0)  
>>> {
>>> +        DRM_NOTE("Skipping %s firmware version check\n",
>>> +             intel_uc_fw_type_repr(uc_fw->type));
>>> +    } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>>> +           uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
>>> +        DRM_NOTE("%s firmware version %d.%d, required %d.%d\n",
>>> +             intel_uc_fw_type_repr(uc_fw->type),
>>> +             uc_fw->major_ver_found, uc_fw->minor_ver_found,
>>> +             uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
>>> +        err = -ENOEXEC;
>>> +        goto fail;
>>> +    }
>>> +
>>> +    DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
>>> +             uc_fw->major_ver_found, uc_fw->minor_ver_found,
>>> +             uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
>>> +
>>> +    obj = i915_gem_object_create_from_data(i915, fw->data, fw->size);
>>> +    if (IS_ERR(obj)) {
>>> +        err = PTR_ERR(obj);
>>> +        goto fail;
>>> +    }
>>> +
>>> +    uc_fw->obj = obj;
>>> +    uc_fw->size = fw->size;
>>> +
>>> +    DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
>>> +             uc_fw->obj);
>>> +
>>> +    release_firmware(fw);
>>> +    uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
>>> +    return;
>>> +
>>> +fail:
>>> +    DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
>>> +         uc_fw->path, err);
>>> +    DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj  
>>> %p\n",
>>> +             err, fw, uc_fw->obj);
>>> +
>>> +    release_firmware(fw);        /* OK even if fw is NULL */
>>> +    uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
>>> +}
>>> diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h  
>>> b/drivers/gpu/drm/i915/intel_uc_fw.h
>>> new file mode 100644
>>> index 0000000..f07c41f
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/i915/intel_uc_fw.h
>>> @@ -0,0 +1,95 @@
>>> +/*
>>> + * Copyright © 2014-2017 Intel Corporation
>>> + *
>>> + * Permission is hereby granted, free of charge, to any person  
>>> obtaining a
>>> + * copy of this software and associated documentation files (the  
>>> "Software"),
>>> + * to deal in the Software without restriction, including without  
>>> limitation
>>> + * the rights to use, copy, modify, merge, publish, distribute,  
>>> sublicense,
>>> + * and/or sell copies of the Software, and to permit persons to whom  
>>> the
>>> + * Software is furnished to do so, subject to the following  
>>> conditions:
>>> + *
>>> + * The above copyright notice and this permission notice (including  
>>> the next
>>> + * paragraph) shall be included in all copies or substantial portions  
>>> of the
>>> + * Software.
>>> + *
>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
>>> EXPRESS OR
>>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
>>> MERCHANTABILITY,
>>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  
>>> SHALL
>>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES  
>>> OR OTHER
>>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  
>>> ARISING
>>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
>>> OTHER DEALINGS
>>> + * IN THE SOFTWARE.
>>> + *
>>> + */
>>> +#ifndef _INTEL_UC_FW_H_
>>> +#define _INTEL_UC_FW_H_
>>> +
>>> +enum intel_uc_fw_status {
>>> +    INTEL_UC_FIRMWARE_FAIL = -1,
>>> +    INTEL_UC_FIRMWARE_NONE = 0,
>>> +    INTEL_UC_FIRMWARE_PENDING,
>>> +    INTEL_UC_FIRMWARE_SUCCESS
>>> +};
>>> +
>>> +enum intel_uc_fw_type {
>>> +    INTEL_UC_FW_TYPE_GUC,
>>> +    INTEL_UC_FW_TYPE_HUC
>>> +};
>>> +
>>> +/*
>>> + * This structure encapsulates all the data needed during the process
>>> + * of fetching, caching, and loading the firmware image into the uC.
>>> + */
>>> +struct intel_uc_fw {
>>> +    const char *path;
>>> +    size_t size;
>>> +    struct drm_i915_gem_object *obj;
>>> +    enum intel_uc_fw_status fetch_status;
>>> +    enum intel_uc_fw_status load_status;
>>> +
>>> +    uint16_t major_ver_wanted;
>>> +    uint16_t minor_ver_wanted;
>>> +    uint16_t major_ver_found;
>>> +    uint16_t minor_ver_found;
>>> +
>>> +    enum intel_uc_fw_type type;
>>> +    uint32_t header_size;
>>> +    uint32_t header_offset;
>>> +    uint32_t rsa_size;
>>> +    uint32_t rsa_offset;
>>> +    uint32_t ucode_size;
>>> +    uint32_t ucode_offset;
>>> +};
>>> +
>>> +static inline
>>> +const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
>>> +{
>>> +    switch (status) {
>>> +    case INTEL_UC_FIRMWARE_FAIL:
>>> +        return "FAIL";
>>> +    case INTEL_UC_FIRMWARE_NONE:
>>> +        return "NONE";
>>> +    case INTEL_UC_FIRMWARE_PENDING:
>>> +        return "PENDING";
>>> +    case INTEL_UC_FIRMWARE_SUCCESS:
>>> +        return "SUCCESS";
>>> +    }
>>> +    return "<invalid>";
>>> +}
>>> +
>>> +static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type  
>>> type)
>>> +{
>>> +    switch (type) {
>>> +    case INTEL_UC_FW_TYPE_GUC:
>>> +        return "GuC";
>>> +    case INTEL_UC_FW_TYPE_HUC:
>>> +        return "HuC";
>>> +    }
>>> +    return "uC";
>>> +}
>>> +
>>> +void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
>>> +void i915_fetch_uc_fw(struct drm_i915_private *i915,
>>> +              struct intel_uc_fw *uc_fw);
>>> +
>>> +#endif
>>


More information about the Intel-gfx mailing list