[PATCH v6 2/2] drm/xe: Add debugfs for IA/GT bias
Vinay Belgaumkar <[email protected]>
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
GT_IA_PERF_BIAS_REG indicates power budget between IA and GT. Lower 16 bits correspond to IA and upper to GT. Higher value indicates more bias towards that plane. The values are in U1.15 format. $ cat /sys/kernel/debug/dri/0/gt0/ia_gt_bias 0x80004000 (GT: 1.000, IA: 0.500) This interface will allow us to observe power budget changes while running workloads and also, if needed, tune it. Bspec: 51878 v3: Add a helper function for U1.15 decode (Michal) v4: Validate input values (Rodrigo) v5: Comments (Michal, Rodrigo) v6: Rename to gt_ia_bias (Anirban), check lower bound (Michal) Cc: Michal Wajdeczko <[email protected]> Cc: Rodrigo Vivi <[email protected]> Signed-off-by: Vinay Belgaumkar <[email protected]> Assisted-by: Copilot:auto --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 6 +++ drivers/gpu/drm/xe/xe_gt_debugfs.c | 80 ++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 08251c7a1a4b..48c515d91882 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -634,6 +634,12 @@ #define GT_GFX_RC6_LOCKED XE_REG(0x138104) #define GT_GFX_RC6 XE_REG(0x138108) +#define GT_IA_PERF_BIAS_REG XE_REG(0x138158) +#define GT_BIAS REG_GENMASK(31, 16) +#define IA_BIAS REG_GENMASK(15, 0) +#define GT_BIAS_DEFAULT 0x10 +#define IA_BIAS_DEFAULT 0x10 + #define GT0_PERF_LIMIT_REASONS XE_REG(0x1381a8) /* Common performance limit reason bits - available on all platforms */ #define GT0_PERF_LIMIT_REASONS_MASK 0xde3 diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c index c38bcacb27e4..ea78b57b1c31 100644 --- a/drivers/gpu/drm/xe/xe_gt_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c @@ -9,7 +9,9 @@ #include <drm/drm_debugfs.h> #include <drm/drm_managed.h> +#include <linux/math.h> +#include "regs/xe_gt_regs.h" #include "xe_device.h" #include "xe_force_wake.h" #include "xe_gt.h" @@ -22,6 +24,7 @@ #include "xe_guc_hwconfig.h" #include "xe_hw_engine.h" #include "xe_lrc.h" +#include "xe_mmio.h" #include "xe_mocs.h" #include "xe_pat.h" #include "xe_pm.h" @@ -336,6 +339,80 @@ static int force_reset_sync_show(struct seq_file *s, void *unused) } DEFINE_SHOW_STORE_ATTRIBUTE(force_reset_sync); +#define U1_15_ONE 0x8000 +#define U1_15_INT_BITS GENMASK(15, 15) +#define U1_15_FRACTION_BITS GENMASK(14, 0) + +static void u1_15_decode(u16 num, u16 *i, u32 *frac) +{ + /* + * In U1.15 format, uppermost bit is integer value and the + * rest 15 are the fraction. + */ + + *i = FIELD_GET(U1_15_INT_BITS, num); + *frac = FIELD_GET(U1_15_FRACTION_BITS, num); +} + +static void u1_15_decode_decimal(u16 value, u16 *i, u32 *frac, int digits) +{ + u1_15_decode(value, i, frac); + *frac = (*frac * int_pow(10, digits)) / (FIELD_MAX(U1_15_FRACTION_BITS) + 1); +} + +static int gt_ia_bias_show(struct seq_file *s, void *unused) +{ + struct xe_gt *gt = s->private; + struct xe_device *xe = gt_to_xe(gt); + u32 val; + u32 ia_frac, gt_frac; + u16 ia_raw, gt_raw; + u16 ia_int, gt_int; + + guard(xe_pm_runtime)(xe); + val = xe_mmio_read32(>->mmio, GT_IA_PERF_BIAS_REG); + + ia_raw = REG_FIELD_GET(IA_BIAS, val); + gt_raw = REG_FIELD_GET(GT_BIAS, val); + + u1_15_decode_decimal(ia_raw, &ia_int, &ia_frac, 4); + u1_15_decode_decimal(gt_raw, >_int, >_frac, 4); + + seq_printf(s, "0x%x (GT: %u.%04u, IA: %u.%04u)\n", + val, gt_int, gt_frac, ia_int, ia_frac); + + return 0; +} + +static ssize_t gt_ia_bias_write(struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct xe_gt *gt = s->private; + struct xe_device *xe = gt_to_xe(gt); + u32 val; + int ret; + + ret = kstrtou32_from_user(userbuf, count, 0, &val); + if (ret) + return ret; + + if (REG_FIELD_GET(IA_BIAS, val) > U1_15_ONE || + REG_FIELD_GET(GT_BIAS, val) > U1_15_ONE) + return -EINVAL; + + if (REG_FIELD_GET(IA_BIAS, val) < IA_BIAS_DEFAULT || + REG_FIELD_GET(GT_BIAS, val) < GT_BIAS_DEFAULT) + return -EINVAL; + + guard(xe_pm_runtime)(xe); + xe_mmio_write32(>->mmio, GT_IA_PERF_BIAS_REG, val); + + return count; +} +DEFINE_SHOW_STORE_ATTRIBUTE(gt_ia_bias); + void xe_gt_debugfs_register(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); @@ -378,6 +455,9 @@ void xe_gt_debugfs_register(struct xe_gt *gt) ARRAY_SIZE(pf_only_debugfs_list), root, minor); + if (xe_gt_is_main_type(gt) && !IS_DGFX(xe) && !IS_SRIOV_VF(xe)) + debugfs_create_file("gt_ia_bias", 0600, root, gt, >_ia_bias_fops); + xe_uc_debugfs_register(>->uc, root); if (IS_SRIOV_PF(xe)) -- 2.38.1