-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/xe: add a new sysfs directory for gtidle properties
1) Add a new sysfs directory under devices/gt#/ called gtidle to contain idle properties of GT such as name, idle_status, idle_residency_ms 2) Remove forcewake calls for residency counter v2: - abstract using function pointers (Anshuman) - remove forcewake calls for residency counter - use device_attr (Badal) - move rc functions to guc_pc - change name to gt_idle (Rodrigo) v3: - return error for drmm_add_action_or_reset - replace file and functions with gt_idle prefix to gt_idle_sysfs (Himal) - use enum for gt idle state - move multiplier to gt idle and initialize (Anshuman) - correct doc annotation (Rodrigo) - remove return variable - use kobj_gt instead of new gtidle kobj - move residency_ms to gtidle file - retain xe_guc_pc prefix for functions in guc_rc file (Michal) v4: - fix doc errors in xe_guc_pc file - change u64 to u32 for reading residency counter - keep gtidle states generic GT_IDLE_C[0/6] (Anshuman) v5: - update commit message to include removal of forcewake calls (Anshuman) - return void from sysfs initialization function and add warnings (Andi) v6: - remove extra lines (Anshuman) Signed-off-by: Riana Tauro <riana.tauro@intel.com> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com> Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
- Loading branch information
Riana Tauro
authored and
Rodrigo Vivi
committed
Dec 21, 2023
1 parent
513e826
commit 1c2097b
Showing
8 changed files
with
239 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
// SPDX-License-Identifier: MIT | ||
/* | ||
* Copyright © 2023 Intel Corporation | ||
*/ | ||
|
||
#include <drm/drm_managed.h> | ||
|
||
#include "xe_device.h" | ||
#include "xe_gt.h" | ||
#include "xe_gt_idle_sysfs.h" | ||
#include "xe_gt_sysfs.h" | ||
#include "xe_guc_pc.h" | ||
|
||
/** | ||
* DOC: Xe GT Idle | ||
* | ||
* Provides sysfs entries for idle properties of GT | ||
* | ||
* device/gt#/gtidle/name - name of the state | ||
* device/gt#/gtidle/idle_residency_ms - Provides residency of the idle state in ms | ||
* device/gt#/gtidle/idle_status - Provides current idle state | ||
*/ | ||
|
||
static struct xe_gt_idle *dev_to_gtidle(struct device *dev) | ||
{ | ||
struct kobject *kobj = &dev->kobj; | ||
|
||
return &kobj_to_gt(kobj->parent)->gtidle; | ||
} | ||
|
||
static struct xe_gt *gtidle_to_gt(struct xe_gt_idle *gtidle) | ||
{ | ||
return container_of(gtidle, struct xe_gt, gtidle); | ||
} | ||
|
||
static struct xe_guc_pc *gtidle_to_pc(struct xe_gt_idle *gtidle) | ||
{ | ||
return >idle_to_gt(gtidle)->uc.guc.pc; | ||
} | ||
|
||
static const char *gt_idle_state_to_string(enum xe_gt_idle_state state) | ||
{ | ||
switch (state) { | ||
case GT_IDLE_C0: | ||
return "gt-c0"; | ||
case GT_IDLE_C6: | ||
return "gt-c6"; | ||
default: | ||
return "unknown"; | ||
} | ||
} | ||
|
||
static u64 get_residency_ms(struct xe_gt_idle *gtidle, u64 cur_residency) | ||
{ | ||
u64 delta, overflow_residency, prev_residency; | ||
|
||
overflow_residency = BIT_ULL(32); | ||
|
||
/* | ||
* Counter wrap handling | ||
* Store previous hw counter values for counter wrap-around handling | ||
* Relying on sufficient frequency of queries otherwise counters can still wrap. | ||
*/ | ||
prev_residency = gtidle->prev_residency; | ||
gtidle->prev_residency = cur_residency; | ||
|
||
/* delta */ | ||
if (cur_residency >= prev_residency) | ||
delta = cur_residency - prev_residency; | ||
else | ||
delta = cur_residency + (overflow_residency - prev_residency); | ||
|
||
/* Add delta to extended raw driver copy of idle residency */ | ||
cur_residency = gtidle->cur_residency + delta; | ||
gtidle->cur_residency = cur_residency; | ||
|
||
/* residency multiplier in ns, convert to ms */ | ||
cur_residency = mul_u64_u32_div(cur_residency, gtidle->residency_multiplier, 1e6); | ||
|
||
return cur_residency; | ||
} | ||
|
||
static ssize_t name_show(struct device *dev, | ||
struct device_attribute *attr, char *buff) | ||
{ | ||
struct xe_gt_idle *gtidle = dev_to_gtidle(dev); | ||
|
||
return sysfs_emit(buff, gtidle->name); | ||
} | ||
static DEVICE_ATTR_RO(name); | ||
|
||
static ssize_t idle_status_show(struct device *dev, | ||
struct device_attribute *attr, char *buff) | ||
{ | ||
struct xe_gt_idle *gtidle = dev_to_gtidle(dev); | ||
struct xe_guc_pc *pc = gtidle_to_pc(gtidle); | ||
enum xe_gt_idle_state state; | ||
|
||
state = gtidle->idle_status(pc); | ||
|
||
return sysfs_emit(buff, "%s\n", gt_idle_state_to_string(state)); | ||
} | ||
static DEVICE_ATTR_RO(idle_status); | ||
|
||
static ssize_t idle_residency_ms_show(struct device *dev, | ||
struct device_attribute *attr, char *buff) | ||
{ | ||
struct xe_gt_idle *gtidle = dev_to_gtidle(dev); | ||
struct xe_guc_pc *pc = gtidle_to_pc(gtidle); | ||
u64 residency; | ||
|
||
residency = gtidle->idle_residency(pc); | ||
return sysfs_emit(buff, "%llu\n", get_residency_ms(gtidle, residency)); | ||
} | ||
static DEVICE_ATTR_RO(idle_residency_ms); | ||
|
||
static const struct attribute *gt_idle_attrs[] = { | ||
&dev_attr_name.attr, | ||
&dev_attr_idle_status.attr, | ||
&dev_attr_idle_residency_ms.attr, | ||
NULL, | ||
}; | ||
|
||
static void gt_idle_sysfs_fini(struct drm_device *drm, void *arg) | ||
{ | ||
struct kobject *kobj = arg; | ||
|
||
sysfs_remove_files(kobj, gt_idle_attrs); | ||
kobject_put(kobj); | ||
} | ||
|
||
void xe_gt_idle_sysfs_init(struct xe_gt_idle *gtidle) | ||
{ | ||
struct xe_gt *gt = gtidle_to_gt(gtidle); | ||
struct xe_device *xe = gt_to_xe(gt); | ||
struct kobject *kobj; | ||
int err; | ||
|
||
kobj = kobject_create_and_add("gtidle", gt->sysfs); | ||
if (!kobj) { | ||
drm_warn(&xe->drm, "%s failed, err: %d\n", __func__, -ENOMEM); | ||
return; | ||
} | ||
|
||
sprintf(gtidle->name, "gt%d-rc\n", gt->info.id); | ||
/* Multiplier for RC6 Residency counter in units of 1.28us */ | ||
gtidle->residency_multiplier = 1280; | ||
gtidle->idle_residency = xe_guc_pc_rc6_residency; | ||
gtidle->idle_status = xe_guc_pc_rc_status; | ||
|
||
err = sysfs_create_files(kobj, gt_idle_attrs); | ||
if (err) { | ||
kobject_put(kobj); | ||
drm_warn(&xe->drm, "failed to register gtidle sysfs, err: %d\n", err); | ||
return; | ||
} | ||
|
||
err = drmm_add_action_or_reset(&xe->drm, gt_idle_sysfs_fini, kobj); | ||
if (err) | ||
drm_warn(&xe->drm, "%s: drmm_add_action_or_reset failed, err: %d\n", | ||
__func__, err); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* SPDX-License-Identifier: MIT */ | ||
/* | ||
* Copyright © 2023 Intel Corporation | ||
*/ | ||
|
||
#ifndef _XE_GT_IDLE_SYSFS_H_ | ||
#define _XE_GT_IDLE_SYSFS_H_ | ||
|
||
#include "xe_gt_idle_sysfs_types.h" | ||
|
||
void xe_gt_idle_sysfs_init(struct xe_gt_idle *gtidle); | ||
|
||
#endif /* _XE_GT_IDLE_SYSFS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* SPDX-License-Identifier: MIT */ | ||
/* | ||
* Copyright © 2023 Intel Corporation | ||
*/ | ||
|
||
#ifndef _XE_GT_IDLE_SYSFS_TYPES_H_ | ||
#define _XE_GT_IDLE_SYSFS_TYPES_H_ | ||
|
||
#include <linux/types.h> | ||
|
||
struct xe_guc_pc; | ||
|
||
/* States of GT Idle */ | ||
enum xe_gt_idle_state { | ||
GT_IDLE_C0, | ||
GT_IDLE_C6, | ||
GT_IDLE_UNKNOWN, | ||
}; | ||
|
||
/** | ||
* struct xe_gt_idle - A struct that contains idle properties based of gt | ||
*/ | ||
struct xe_gt_idle { | ||
/** @name: name */ | ||
char name[16]; | ||
/** @residency_multiplier: residency multiplier in ns */ | ||
u32 residency_multiplier; | ||
/** @cur_residency: raw driver copy of idle residency */ | ||
u64 cur_residency; | ||
/** @prev_residency: previous residency counter */ | ||
u64 prev_residency; | ||
/** @idle_status: get the current idle state */ | ||
enum xe_gt_idle_state (*idle_status)(struct xe_guc_pc *pc); | ||
/** @idle_residency: get idle residency counter */ | ||
u64 (*idle_residency)(struct xe_guc_pc *pc); | ||
}; | ||
|
||
#endif /* _XE_GT_IDLE_SYSFS_TYPES_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters