Commit 242c4b91 authored by Daniele Ceraolo Spurio's avatar Daniele Ceraolo Spurio
Browse files

drm/i915/uc: Introduce GSC FW



On MTL the GSC FW needs to be loaded on the media GT by the graphics
driver. We're going to treat it like a new uc_fw, so add the initial
defs and init/fini functions for it.

Similarly to the other FWs, the GSC FW path can be overridden via
modparam. The modparam can also be used to disable the GSC FW loading by
setting it to an empty string.

Note that the new structure has been called intel_gsc_uc to avoid
confusion with the existing intel_gsc, which instead represents the heci
gsc interfaces.

v2: re-order Makefile list to be properly sorted (Jani, Alan), better
    comment (alan)

Signed-off-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Reviewed-by: default avatarAlan Previn <alan.previn.teres.alexis@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221208200521.2928378-2-daniele.ceraolospurio@intel.com
parent 95c713d7
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -188,9 +188,8 @@ i915-y += \
	  i915_vma_resource.o

# general-purpose microcontroller (GuC) support
i915-y += gt/uc/intel_uc.o \
	  gt/uc/intel_uc_debugfs.o \
	  gt/uc/intel_uc_fw.o \
i915-y += \
	  gt/uc/intel_gsc_uc.o \
	  gt/uc/intel_guc.o \
	  gt/uc/intel_guc_ads.o \
	  gt/uc/intel_guc_capture.o \
@@ -205,7 +204,10 @@ i915-y += gt/uc/intel_uc.o \
	  gt/uc/intel_guc_submission.o \
	  gt/uc/intel_huc.o \
	  gt/uc/intel_huc_debugfs.o \
	  gt/uc/intel_huc_fw.o
	  gt/uc/intel_huc_fw.o \
	  gt/uc/intel_uc.o \
	  gt/uc/intel_uc_debugfs.o \
	  gt/uc/intel_uc_fw.o

# graphics system controller (GSC) support
i915-y += gt/intel_gsc.o
+5 −0
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
	return container_of(huc, struct intel_gt, uc.huc);
}

static inline struct intel_gt *gsc_uc_to_gt(struct intel_gsc_uc *gsc_uc)
{
	return container_of(gsc_uc, struct intel_gt, uc.gsc);
}

static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
{
	return container_of(gsc, struct intel_gt, gsc);
+70 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include <linux/types.h>

#include "gt/intel_gt.h"
#include "intel_gsc_uc.h"
#include "i915_drv.h"

static bool gsc_engine_supported(struct intel_gt *gt)
{
	intel_engine_mask_t mask;

	/*
	 * We reach here from i915_driver_early_probe for the primary GT before
	 * its engine mask is set, so we use the device info engine mask for it.
	 * For other GTs we expect the GT-specific mask to be set before we
	 * call this function.
	 */
	GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);

	if (gt_is_root(gt))
		mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
	else
		mask = gt->info.engine_mask;

	return __HAS_ENGINE(mask, GSC0);
}

void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
{
	intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);

	/* we can arrive here from i915_driver_early_probe for primary
	 * GT with it being not fully setup hence check device info's
	 * engine mask
	 */
	if (!gsc_engine_supported(gsc_uc_to_gt(gsc))) {
		intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
		return;
	}
}

int intel_gsc_uc_init(struct intel_gsc_uc *gsc)
{
	struct drm_i915_private *i915 = gsc_uc_to_gt(gsc)->i915;
	int err;

	err = intel_uc_fw_init(&gsc->fw);
	if (err)
		goto out;

	intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_LOADABLE);

	return 0;

out:
	i915_probe_error(i915, "failed with %d\n", err);
	return err;
}

void intel_gsc_uc_fini(struct intel_gsc_uc *gsc)
{
	if (!intel_uc_fw_is_loadable(&gsc->fw))
		return;

	intel_uc_fw_fini(&gsc->fw);
}
+36 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2022 Intel Corporation
 */

#ifndef _INTEL_GSC_UC_H_
#define _INTEL_GSC_UC_H_

#include "intel_uc_fw.h"

struct intel_gsc_uc {
	/* Generic uC firmware management */
	struct intel_uc_fw fw;
};

void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc);
int intel_gsc_uc_init(struct intel_gsc_uc *gsc);
void intel_gsc_uc_fini(struct intel_gsc_uc *gsc);

static inline bool intel_gsc_uc_is_supported(struct intel_gsc_uc *gsc)
{
	return intel_uc_fw_is_supported(&gsc->fw);
}

static inline bool intel_gsc_uc_is_wanted(struct intel_gsc_uc *gsc)
{
	return intel_uc_fw_is_enabled(&gsc->fw);
}

static inline bool intel_gsc_uc_is_used(struct intel_gsc_uc *gsc)
{
	GEM_BUG_ON(__intel_uc_fw_status(&gsc->fw) == INTEL_UC_FIRMWARE_SELECTED);
	return intel_uc_fw_is_available(&gsc->fw);
}

#endif
+17 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#include "gt/intel_gt.h"
#include "gt/intel_reset.h"
#include "intel_gsc_uc.h"
#include "intel_guc.h"
#include "intel_guc_ads.h"
#include "intel_guc_submission.h"
@@ -126,6 +127,7 @@ void intel_uc_init_early(struct intel_uc *uc)

	intel_guc_init_early(&uc->guc);
	intel_huc_init_early(&uc->huc);
	intel_gsc_uc_init_early(&uc->gsc);

	__confirm_options(uc);

@@ -296,15 +298,26 @@ static void __uc_fetch_firmwares(struct intel_uc *uc)
						  INTEL_UC_FIRMWARE_ERROR);
		}

		if (intel_uc_wants_gsc_uc(uc)) {
			drm_dbg(&uc_to_gt(uc)->i915->drm,
				"Failed to fetch GuC: %d disabling GSC\n", err);
			intel_uc_fw_change_status(&uc->gsc.fw,
						  INTEL_UC_FIRMWARE_ERROR);
		}

		return;
	}

	if (intel_uc_wants_huc(uc))
		intel_uc_fw_fetch(&uc->huc.fw);

	if (intel_uc_wants_gsc_uc(uc))
		intel_uc_fw_fetch(&uc->gsc.fw);
}

static void __uc_cleanup_firmwares(struct intel_uc *uc)
{
	intel_uc_fw_cleanup_fetch(&uc->gsc.fw);
	intel_uc_fw_cleanup_fetch(&uc->huc.fw);
	intel_uc_fw_cleanup_fetch(&uc->guc.fw);
}
@@ -330,11 +343,15 @@ static int __uc_init(struct intel_uc *uc)
	if (intel_uc_uses_huc(uc))
		intel_huc_init(huc);

	if (intel_uc_uses_gsc_uc(uc))
		intel_gsc_uc_init(&uc->gsc);

	return 0;
}

static void __uc_fini(struct intel_uc *uc)
{
	intel_gsc_uc_fini(&uc->gsc);
	intel_huc_fini(&uc->huc);
	intel_guc_fini(&uc->guc);
}
Loading