Signed-off-by: John Harrison <John.C.Harrison@xxxxxxxxx>
---
drivers/gpu/drm/i915/gt/intel_engine_types.h | 4 +-
.../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h | 4 +-
drivers/gpu/drm/i915/gt/uc/intel_guc.h | 82 ++--
drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 55 ++-
drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h | 9 +-
drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 23 +-
.../gpu/drm/i915/gt/uc/intel_guc_submission.c | 381 ++++++++++++++----
7 files changed, 427 insertions(+), 131 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index a7e6775980043..40fd8f984d64b 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -323,7 +323,7 @@ struct intel_engine_execlists_stats {
ktime_t start;
};
-struct intel_engine_guc_stats {
+struct intel_engine_guc_stats_v1 {
/**
* @running: Active state of the engine when busyness was last
sampled.
*/
@@ -603,7 +603,7 @@ struct intel_engine_cs {
struct {
union {
struct intel_engine_execlists_stats execlists;
- struct intel_engine_guc_stats guc;
+ struct intel_engine_guc_stats_v1 guc_v1;
};
/**
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index f359bef046e0b..c190a99a36c38 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -137,7 +137,9 @@ enum intel_guc_action {
INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
- INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
+ INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF_V1 = 0x550A,
+ INTEL_GUC_ACTION_SET_DEVICE_ENGINE_UTILIZATION_V2 = 0x550C,
+ INTEL_GUC_ACTION_SET_FUNCTION_ENGINE_UTILIZATION_V2 = 0x550D,
INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 6c392bad29c19..e6502ab5f049f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -226,45 +226,61 @@ struct intel_guc {
struct mutex send_mutex;
/**
- * @timestamp: GT timestamp object that stores a copy of the
timestamp
- * and adjusts it for overflow using a worker.
+ * @busy: Data used by the different versions of engine busyness
implementations.
*/
- struct {
- /**
- * @lock: Lock protecting the below fields and the engine
stats.
- */
- spinlock_t lock;
-
- /**
- * @gt_stamp: 64 bit extended value of the GT timestamp.
- */
- u64 gt_stamp;
-
- /**
- * @ping_delay: Period for polling the GT timestamp for
- * overflow.
- */
- unsigned long ping_delay;
-
- /**
- * @work: Periodic work to adjust GT timestamp, engine and
- * context usage for overflows.
- */
- struct delayed_work work;
-
+ union {
/**
- * @shift: Right shift value for the gpm timestamp
+ * @v1: Data used by v1 engine busyness implementation.
Mostly a copy
+ * of the GT timestamp extended to 64 bits and the worker
for maintaining it.
*/
- u32 shift;
+ struct {
+ /**
+ * @lock: Lock protecting the below fields and the
engine stats.
+ */
+ spinlock_t lock;
+
+ /**
+ * @gt_stamp: 64 bit extended value of the GT timestamp.
+ */
+ u64 gt_stamp;
+
+ /**
+ * @ping_delay: Period for polling the GT timestamp for
+ * overflow.
+ */
+ unsigned long ping_delay;
+
+ /**
+ * @work: Periodic work to adjust GT timestamp, engine and
+ * context usage for overflows.
+ */
+ struct delayed_work work;
+
+ /**
+ * @shift: Right shift value for the gpm timestamp
+ */
+ u32 shift;
+
+ /**
+ * @last_stat_jiffies: jiffies at last actual stats
collection time
+ * We use this timestamp to ensure we don't oversample the
+ * stats because runtime power management events can
trigger
+ * stats collection at much higher rates than required.
+ */
+ unsigned long last_stat_jiffies;
+ } v1;
/**
- * @last_stat_jiffies: jiffies at last actual stats
collection time
- * We use this timestamp to ensure we don't oversample the
- * stats because runtime power management events can trigger
- * stats collection at much higher rates than required.
+ * @v2: Data used by v2 engine busyness implementation - a
memory object
+ * that is filled in by the GuC and read by the driver.
*/
- unsigned long last_stat_jiffies;
- } timestamp;
+ struct {
+ /** @device_vma: object allocated to hold the device
level busyness data */
+ struct i915_vma *device_vma;
+ /** @device_map: access object for @device_vma */
+ struct iosys_map device_map;
+ } v2;
+ } busy;
/**
* @dead_guc_worker: Asynchronous worker thread for forcing a GuC
reset.
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 63724e17829a7..1ce595d6816f7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -59,7 +59,10 @@ struct __guc_ads_blob {
struct guc_ads ads;
struct guc_policies policies;
struct guc_gt_system_info system_info;
- struct guc_engine_usage engine_usage;
+ union {
+ struct guc_engine_usage v1;
+ struct guc_function_observation_data v2;
+ } engine_usage;
/* From here on, location is dynamic! Refer to above diagram. */
struct guc_mmio_reg regset[];
} __packed;
@@ -948,18 +951,62 @@ void intel_guc_ads_reset(struct intel_guc *guc)
guc_ads_private_data_reset(guc);
}
-u32 intel_guc_engine_usage_offset(struct intel_guc *guc)
+u32 intel_guc_engine_usage_offset_pf(struct intel_guc *guc)
{
return intel_guc_ggtt_offset(guc, guc->ads_vma) +
offsetof(struct __guc_ads_blob, engine_usage);
}
-struct iosys_map intel_guc_engine_usage_record_map(struct
intel_engine_cs *engine)
+struct iosys_map intel_guc_engine_usage_record_map_v1(struct
intel_engine_cs *engine)
{
struct intel_guc *guc = &engine->gt->uc.guc;
u8 guc_class = engine_class_to_guc_class(engine->class);
size_t offset = offsetof(struct __guc_ads_blob,
- engine_usage.engines[guc_class][ilog2(engine->logical_mask)]);
+ engine_usage.v1.engines[guc_class][ilog2(engine->logical_mask)]);
return IOSYS_MAP_INIT_OFFSET(&guc->ads_map, offset);
}
+
+int intel_guc_engine_usage_record_map_v2(struct intel_guc *guc,
+ struct intel_engine_cs *engine,
+ u32 guc_vf,
+ struct iosys_map *engine_map,
+ struct iosys_map *global_map)
+{
+ size_t offset_global, offset_engine;
+ struct iosys_map *map;
+ u32 instance;
+ u8 guc_class;
+
+ if (engine) {