drm/xe/uc: Split xe_uc_fw_init
authorMichał Winiarski <michal.winiarski@intel.com>
Tue, 5 Dec 2023 01:33:05 +0000 (02:33 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:45:12 +0000 (11:45 -0500)
The function does a driver specific "request firmware" step that
includes validating the input, followed by wrapping the firmware binary
into a buffer object. Split it into smaller parts.

Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_uc_fw.c

index 8ad4bca..f258eb4 100644 (file)
@@ -635,15 +635,12 @@ do { \
                          ver_->major, ver_->minor, ver_->patch); \
 } while (0)
 
-int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
+static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmware_p)
 {
        struct xe_device *xe = uc_fw_to_xe(uc_fw);
-       struct xe_gt *gt = uc_fw_to_gt(uc_fw);
-       struct xe_tile *tile = gt_to_tile(gt);
        struct device *dev = xe->drm.dev;
        struct drm_printer p = drm_info_printer(dev);
        const struct firmware *fw = NULL;
-       struct xe_bo *obj;
        int err;
 
        /*
@@ -691,9 +688,39 @@ int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
                        goto fail;
        }
 
-       obj = xe_managed_bo_create_from_data(xe, tile, fw->data, fw->size,
-                                            XE_BO_CREATE_VRAM_IF_DGFX(tile) |
-                                            XE_BO_CREATE_GGTT_BIT);
+       *firmware_p = fw;
+
+       return 0;
+
+fail:
+       xe_uc_fw_change_status(uc_fw, err == -ENOENT ?
+                              XE_UC_FIRMWARE_MISSING :
+                              XE_UC_FIRMWARE_ERROR);
+
+       drm_notice(&xe->drm, "%s firmware %s: fetch failed with error %d\n",
+                  xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
+       drm_info(&xe->drm, "%s firmware(s) can be downloaded from %s\n",
+                xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);
+
+       release_firmware(fw);           /* OK even if fw is NULL */
+
+       return err;
+}
+
+static void uc_fw_release(const struct firmware *fw)
+{
+       release_firmware(fw);
+}
+
+static int uc_fw_copy(struct xe_uc_fw *uc_fw, const void *data, size_t size, u32 flags)
+{
+       struct xe_device *xe = uc_fw_to_xe(uc_fw);
+       struct xe_gt *gt = uc_fw_to_gt(uc_fw);
+       struct xe_tile *tile = gt_to_tile(gt);
+       struct xe_bo *obj;
+       int err;
+
+       obj = xe_managed_bo_create_from_data(xe, tile, data, size, flags);
        if (IS_ERR(obj)) {
                drm_notice(&xe->drm, "%s firmware %s: failed to create / populate bo",
                           xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
@@ -702,28 +729,43 @@ int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
        }
 
        uc_fw->bo = obj;
-       uc_fw->size = fw->size;
-       xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_AVAILABLE);
+       uc_fw->size = size;
 
-       release_firmware(fw);
+       xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_AVAILABLE);
 
        err = drmm_add_action_or_reset(&xe->drm, uc_fw_fini, uc_fw);
        if (err)
-               return err;
+               goto fail;
 
        return 0;
 
 fail:
-       xe_uc_fw_change_status(uc_fw, err == -ENOENT ?
-                              XE_UC_FIRMWARE_MISSING :
-                              XE_UC_FIRMWARE_ERROR);
-
-       drm_notice(&xe->drm, "%s firmware %s: fetch failed with error %d\n",
+       xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_ERROR);
+       drm_notice(&xe->drm, "%s firmware %s: copy failed with error %d\n",
                   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
-       drm_info(&xe->drm, "%s firmware(s) can be downloaded from %s\n",
-                xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);
 
-       release_firmware(fw);           /* OK even if fw is NULL */
+       return err;
+}
+
+int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
+{
+       const struct firmware *fw = NULL;
+       struct xe_gt *gt = uc_fw_to_gt(uc_fw);
+       struct xe_tile *tile = gt_to_tile(gt);
+       int err;
+
+       err = uc_fw_request(uc_fw, &fw);
+       if (err)
+               return err;
+
+       /* no error and no firmware means nothing to copy */
+       if (!fw)
+               return 0;
+
+       err = uc_fw_copy(uc_fw, fw->data, fw->size,
+                        XE_BO_CREATE_VRAM_IF_DGFX(tile) | XE_BO_CREATE_GGTT_BIT);
+
+       uc_fw_release(fw);
 
        return err;
 }