Commit 561055b8 authored by Daniele Ceraolo Spurio's avatar Daniele Ceraolo Spurio
Browse files

drm/i915/mtl/gsc: Add a gsc_info debugfs



Add a new debugfs to dump information about the GSC. This includes:

- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

Note that those are the same registers that the mei driver dumps in
their own status sysfs on DG2 (where mei owns the GSC).

To make it simpler to loop through the status register, the code has
been update to use a PICK macro and the existing code using the regs had
been adapted to match.

v2: fix includes and copyright dates (Alan)
v3: actually fix the includes

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>
Reviewed-by: default avatarAlan Previn <alan.previn.teres.alexis@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230612181529.2222451-5-daniele.ceraolospurio@intel.com
parent a6c13a23
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -196,6 +196,7 @@ i915-y += \
	  gt/uc/intel_gsc_fw.o \
	  gt/uc/intel_gsc_proxy.o \
	  gt/uc/intel_gsc_uc.o \
	  gt/uc/intel_gsc_uc_debugfs.o \
	  gt/uc/intel_gsc_uc_heci_cmd_submit.o \
	  gt/uc/intel_guc.o \
	  gt/uc/intel_guc_ads.o \
+12 −16
Original line number Diff line number Diff line
@@ -12,19 +12,14 @@
#include "intel_gsc_binary_headers.h"
#include "intel_gsc_fw.h"
#include "intel_gsc_uc_heci_cmd_submit.h"

#define GSC_FW_STATUS_REG			_MMIO(0x116C40)
#define GSC_FW_CURRENT_STATE			REG_GENMASK(3, 0)
#define   GSC_FW_CURRENT_STATE_RESET		0
#define   GSC_FW_PROXY_STATE_NORMAL		5
#define GSC_FW_INIT_COMPLETE_BIT		REG_BIT(9)
#include "i915_reg.h"

static bool gsc_is_in_reset(struct intel_uncore *uncore)
{
	u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
	u32 fw_status = intel_uncore_read(uncore, HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));

	return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
	       GSC_FW_CURRENT_STATE_RESET;
	return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
			HECI1_FWSTS1_CURRENT_STATE_RESET;
}

static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)
@@ -33,21 +28,22 @@ static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)
	u32 fw_status = 0;

	with_intel_runtime_pm(uncore->rpm, wakeref)
		fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
		fw_status = intel_uncore_read(uncore, HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));

	return fw_status;
}

bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
{
	return REG_FIELD_GET(GSC_FW_CURRENT_STATE,
	return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE,
			     gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore)) ==
	       GSC_FW_PROXY_STATE_NORMAL;
	       HECI1_FWSTS1_PROXY_STATE_NORMAL;
}

bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
{
	return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) & GSC_FW_INIT_COMPLETE_BIT;
	return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) &
	       HECI1_FWSTS1_INIT_COMPLETE;
}

static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
@@ -298,9 +294,9 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
static int gsc_fw_wait(struct intel_gt *gt)
{
	return intel_wait_for_register(gt->uncore,
				       GSC_FW_STATUS_REG,
				       GSC_FW_INIT_COMPLETE_BIT,
				       GSC_FW_INIT_COMPLETE_BIT,
				       HECI_FWSTS(MTL_GSC_HECI1_BASE, 1),
				       HECI1_FWSTS1_INIT_COMPLETE,
				       HECI1_FWSTS1_INIT_COMPLETE,
				       500);
}

+45 −2
Original line number Diff line number Diff line
@@ -7,10 +7,11 @@

#include "gt/intel_gt.h"
#include "gt/intel_gt_print.h"
#include "intel_gsc_uc.h"
#include "intel_gsc_fw.h"
#include "i915_drv.h"
#include "intel_gsc_proxy.h"
#include "intel_gsc_uc.h"
#include "i915_drv.h"
#include "i915_reg.h"

static void gsc_work(struct work_struct *work)
{
@@ -304,3 +305,45 @@ void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc)

	queue_work(gsc->wq, &gsc->work);
}

void intel_gsc_uc_load_status(struct intel_gsc_uc *gsc, struct drm_printer *p)
{
	struct intel_gt *gt = gsc_uc_to_gt(gsc);
	struct intel_uncore *uncore = gt->uncore;
	intel_wakeref_t wakeref;

	if (!intel_gsc_uc_is_supported(gsc)) {
		drm_printf(p, "GSC not supported\n");
		return;
	}

	if (!intel_gsc_uc_is_wanted(gsc)) {
		drm_printf(p, "GSC disabled\n");
		return;
	}

	drm_printf(p, "GSC firmware: %s\n", gsc->fw.file_selected.path);
	if (gsc->fw.file_selected.path != gsc->fw.file_wanted.path)
		drm_printf(p, "GSC firmware wanted: %s\n", gsc->fw.file_wanted.path);
	drm_printf(p, "\tstatus: %s\n", intel_uc_fw_status_repr(gsc->fw.status));

	drm_printf(p, "Release: %u.%u.%u.%u\n",
		   gsc->release.major, gsc->release.minor,
		   gsc->release.patch, gsc->release.build);

	drm_printf(p, "Compatibility Version: %u.%u [min expected %u.%u]\n",
		   gsc->fw.file_selected.ver.major, gsc->fw.file_selected.ver.minor,
		   gsc->fw.file_wanted.ver.major, gsc->fw.file_wanted.ver.minor);

	drm_printf(p, "SVN: %u\n", gsc->security_version);

	with_intel_runtime_pm(uncore->rpm, wakeref) {
		u32 i;

		for (i = 1; i <= 6; i++) {
			u32 status = intel_uncore_read(uncore,
						       HECI_FWSTS(MTL_GSC_HECI1_BASE, i));
			drm_printf(p, "HECI1 FWSTST%u = 0x%08x\n", i, status);
		}
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

#include "intel_uc_fw.h"

struct drm_printer;
struct i915_vma;
struct intel_context;
struct i915_gsc_proxy_component;
@@ -63,6 +64,7 @@ void intel_gsc_uc_suspend(struct intel_gsc_uc *gsc);
void intel_gsc_uc_resume(struct intel_gsc_uc *gsc);
void intel_gsc_uc_flush_work(struct intel_gsc_uc *gsc);
void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc);
void intel_gsc_uc_load_status(struct intel_gsc_uc *gsc, struct drm_printer *p);

static inline bool intel_gsc_uc_is_supported(struct intel_gsc_uc *gsc)
{
+39 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include <drm/drm_print.h>

#include "gt/intel_gt.h"
#include "gt/intel_gt_debugfs.h"
#include "gt/intel_gt_print.h"
#include "intel_gsc_uc.h"
#include "intel_gsc_uc_debugfs.h"
#include "i915_drv.h"

static int gsc_info_show(struct seq_file *m, void *data)
{
	struct drm_printer p = drm_seq_file_printer(m);
	struct intel_gsc_uc *gsc = m->private;

	if (!intel_gsc_uc_is_supported(gsc))
		return -ENODEV;

	intel_gsc_uc_load_status(gsc, &p);

	return 0;
}
DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(gsc_info);

void intel_gsc_uc_debugfs_register(struct intel_gsc_uc *gsc_uc, struct dentry *root)
{
	static const struct intel_gt_debugfs_file files[] = {
		{ "gsc_info", &gsc_info_fops, NULL },
	};

	if (!intel_gsc_uc_is_supported(gsc_uc))
		return;

	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), gsc_uc);
}
Loading