aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Winiarski <[email protected]>2023-12-05 02:33:05 +0100
committerRodrigo Vivi <[email protected]>2023-12-21 11:45:12 -0500
commitc93ea05191c5b67ecaa784085f8a73e02abcfc76 (patch)
tree092e1d38f9d9638935e35978efe531d7e5b92a2e
parent0e1a47fcabc8ffa6f460c60c2caa04e51170fa22 (diff)
drm/xe/uc: Split xe_uc_fw_init
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 <[email protected]> Reviewed-by: Matt Roper <[email protected]> Signed-off-by: Rodrigo Vivi <[email protected]>
-rw-r--r--drivers/gpu/drm/xe/xe_uc_fw.c80
1 files changed, 61 insertions, 19 deletions
diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c
index 8ad4bcabb8b5..f258eb44fe31 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw.c
+++ b/drivers/gpu/drm/xe/xe_uc_fw.c
@@ -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;
}