Commit 396044c9 authored by Maarten Lankhorst's avatar Maarten Lankhorst
Browse files

drm/xe: Simplify GuC early initialization

Add a 2-stage GuC init. An early one for everything that is needed
for VF, and a full one that loads GuC and is allowed to do allocations.

Link: https://lore.kernel.org/r/20250619104858.418440-16-dev@lankhorst.se


Signed-off-by: default avatarMaarten Lankhorst <dev@lankhorst.se>
Reviewed-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
parent b3412d72
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -426,7 +426,7 @@ int xe_gt_init_early(struct xe_gt *gt)
	 */
	xe_gt_mmio_init(gt);

	return 0;
	return xe_uc_init_noalloc(&gt->uc);
}

static void dump_pat_on_error(struct xe_gt *gt)
+32 −19
Original line number Diff line number Diff line
@@ -627,21 +627,11 @@ static int xe_guc_realloc_post_hwconfig(struct xe_guc *guc)
	return 0;
}

static int vf_guc_init(struct xe_guc *guc)
static int vf_guc_init_noalloc(struct xe_guc *guc)
{
	struct xe_gt *gt = guc_to_gt(guc);
	int err;

	xe_guc_comm_init_early(guc);

	err = xe_guc_ct_init(&guc->ct);
	if (err)
		return err;

	err = xe_guc_relay_init(&guc->relay);
	if (err)
		return err;

	err = xe_gt_sriov_vf_bootstrap(gt);
	if (err)
		return err;
@@ -653,6 +643,35 @@ static int vf_guc_init(struct xe_guc *guc)
	return 0;
}

int xe_guc_init_noalloc(struct xe_guc *guc)
{
	struct xe_device *xe = guc_to_xe(guc);
	struct xe_gt *gt = guc_to_gt(guc);
	int ret;

	xe_guc_comm_init_early(guc);

	ret = xe_guc_ct_init_noalloc(&guc->ct);
	if (ret)
		goto out;

	ret = xe_guc_relay_init(&guc->relay);
	if (ret)
		goto out;

	if (IS_SRIOV_VF(xe)) {
		ret = vf_guc_init_noalloc(guc);
		if (ret)
			goto out;
	}

	return 0;

out:
	xe_gt_err(gt, "GuC init failed with %pe\n", ERR_PTR(ret));
	return ret;
}

int xe_guc_init(struct xe_guc *guc)
{
	struct xe_device *xe = guc_to_xe(guc);
@@ -662,13 +681,13 @@ int xe_guc_init(struct xe_guc *guc)
	guc->fw.type = XE_UC_FW_TYPE_GUC;
	ret = xe_uc_fw_init(&guc->fw);
	if (ret)
		goto out;
		return ret;

	if (!xe_uc_fw_is_enabled(&guc->fw))
		return 0;

	if (IS_SRIOV_VF(xe)) {
		ret = vf_guc_init(guc);
		ret = xe_guc_ct_init(&guc->ct);
		if (ret)
			goto out;
		return 0;
@@ -690,10 +709,6 @@ int xe_guc_init(struct xe_guc *guc)
	if (ret)
		goto out;

	ret = xe_guc_relay_init(&guc->relay);
	if (ret)
		goto out;

	xe_uc_fw_change_status(&guc->fw, XE_UC_FIRMWARE_LOADABLE);

	ret = devm_add_action_or_reset(xe->drm.dev, guc_fini_hw, guc);
@@ -702,8 +717,6 @@ int xe_guc_init(struct xe_guc *guc)

	guc_init_params(guc);

	xe_guc_comm_init_early(guc);

	return 0;

out:
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
struct drm_printer;

void xe_guc_comm_init_early(struct xe_guc *guc);
int xe_guc_init_noalloc(struct xe_guc *guc);
int xe_guc_init(struct xe_guc *guc);
int xe_guc_init_post_hwconfig(struct xe_guc *guc);
int xe_guc_post_load_init(struct xe_guc *guc);
+18 −10
Original line number Diff line number Diff line
@@ -209,12 +209,10 @@ static void primelockdep(struct xe_guc_ct *ct)
	fs_reclaim_release(GFP_KERNEL);
}

int xe_guc_ct_init(struct xe_guc_ct *ct)
int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct)
{
	struct xe_device *xe = ct_to_xe(ct);
	struct xe_gt *gt = ct_to_gt(ct);
	struct xe_tile *tile = gt_to_tile(gt);
	struct xe_bo *bo;
	int err;

	xe_gt_assert(gt, !(guc_ct_size() % PAGE_SIZE));
@@ -240,6 +238,23 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)

	primelockdep(ct);

	err = drmm_add_action_or_reset(&xe->drm, guc_ct_fini, ct);
	if (err)
		return err;

	xe_gt_assert(gt, ct->state == XE_GUC_CT_STATE_NOT_INITIALIZED);
	ct->state = XE_GUC_CT_STATE_DISABLED;
	return 0;
}
ALLOW_ERROR_INJECTION(xe_guc_ct_init_noalloc, ERRNO); /* See xe_pci_probe() */

int xe_guc_ct_init(struct xe_guc_ct *ct)
{
	struct xe_device *xe = ct_to_xe(ct);
	struct xe_gt *gt = ct_to_gt(ct);
	struct xe_tile *tile = gt_to_tile(gt);
	struct xe_bo *bo;

	bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
					  XE_BO_FLAG_SYSTEM |
					  XE_BO_FLAG_GGTT |
@@ -249,13 +264,6 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
		return PTR_ERR(bo);

	ct->bo = bo;

	err = drmm_add_action_or_reset(&xe->drm, guc_ct_fini, ct);
	if (err)
		return err;

	xe_gt_assert(gt, ct->state == XE_GUC_CT_STATE_NOT_INITIALIZED);
	ct->state = XE_GUC_CT_STATE_DISABLED;
	return 0;
}
ALLOW_ERROR_INJECTION(xe_guc_ct_init, ERRNO); /* See xe_pci_probe() */
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
struct drm_printer;
struct xe_device;

int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct);
int xe_guc_ct_init(struct xe_guc_ct *ct);
int xe_guc_ct_enable(struct xe_guc_ct *ct);
void xe_guc_ct_disable(struct xe_guc_ct *ct);
Loading