]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe: Add forcewake status to powergate_info
authorVinay Belgaumkar <vinay.belgaumkar@intel.com>
Wed, 4 Feb 2026 19:03:14 +0000 (11:03 -0800)
committerVinay Belgaumkar <vinay.belgaumkar@intel.com>
Thu, 5 Feb 2026 22:33:44 +0000 (14:33 -0800)
Dump forcewake status and ref counts for all domains as part
of this debugfs. This is the sample output from gt1-

$ cat /sys/kernel/debug/dri//0/gt1/powergate_info
Media Power Gating Enabled: yes
Media Slice0 Power Gate Status: down
GSC Power Gate Status: down
GT.ref_count=0, GT.forcewake=0x10000
VDBox0.ref_count=0, VDBox0.forcewake=0x10000
VEBox0.ref_count=0, VEBox0.forcewake=0x10000
GSC.ref_count=0, GSC.forcewake=0x10000

v2: Fix checkpatch issues

Reviewed-by: Badal Nilawar <badal.nilawar@intel.com>
Signed-off-by: Vinay Belgaumkar<vinay.belgaumkar@intel.com>
Link: https://patch.msgid.link/20260204190314.2904009-3-vinay.belgaumkar@intel.com
drivers/gpu/drm/xe/xe_force_wake.c
drivers/gpu/drm/xe/xe_force_wake.h
drivers/gpu/drm/xe/xe_gt_idle.c

index 76e054f314ee1584ae53f7e5de74fc938592c3c0..197e2197bd0a300e4e83e5653b07eb861b39c6e2 100644 (file)
@@ -148,12 +148,6 @@ static int domain_sleep_wait(struct xe_gt *gt,
        return __domain_wait(gt, domain, false);
 }
 
-#define for_each_fw_domain_masked(domain__, mask__, fw__, tmp__) \
-       for (tmp__ = (mask__); tmp__; tmp__ &= ~BIT(ffs(tmp__) - 1)) \
-               for_each_if((domain__ = ((fw__)->domains + \
-                                        (ffs(tmp__) - 1))) && \
-                                        domain__->reg_ctl.addr)
-
 /**
  * xe_force_wake_get() : Increase the domain refcount
  * @fw: struct xe_force_wake
@@ -266,3 +260,43 @@ void xe_force_wake_put(struct xe_force_wake *fw, unsigned int fw_ref)
        xe_gt_WARN(gt, ack_fail, "Forcewake domain%s %#x failed to acknowledge sleep request\n",
                   str_plural(hweight_long(ack_fail)), ack_fail);
 }
+
+const char *xe_force_wake_domain_to_str(enum xe_force_wake_domain_id id)
+{
+       switch (id) {
+       case XE_FW_DOMAIN_ID_GT:
+               return "GT";
+       case XE_FW_DOMAIN_ID_RENDER:
+               return "Render";
+       case XE_FW_DOMAIN_ID_MEDIA:
+               return "Media";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX0:
+               return "VDBox0";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX1:
+               return "VDBox1";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX2:
+               return "VDBox2";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX3:
+               return "VDBox3";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX4:
+               return "VDBox4";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX5:
+               return "VDBox5";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX6:
+               return "VDBox6";
+       case XE_FW_DOMAIN_ID_MEDIA_VDBOX7:
+               return "VDBox7";
+       case XE_FW_DOMAIN_ID_MEDIA_VEBOX0:
+               return "VEBox0";
+       case XE_FW_DOMAIN_ID_MEDIA_VEBOX1:
+               return "VEBox1";
+       case XE_FW_DOMAIN_ID_MEDIA_VEBOX2:
+               return "VEBox2";
+       case XE_FW_DOMAIN_ID_MEDIA_VEBOX3:
+               return "VEBox3";
+       case XE_FW_DOMAIN_ID_GSC:
+               return "GSC";
+       default:
+               return "Unknown";
+       }
+}
index 1e2198f6a007835d7bf5b977d64dac35f6a99ad5..e2721f205d6c5d0642d198b6194ebbbacb2130aa 100644 (file)
@@ -19,6 +19,17 @@ unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
                                            enum xe_force_wake_domains domains);
 void xe_force_wake_put(struct xe_force_wake *fw, unsigned int fw_ref);
 
+const char *xe_force_wake_domain_to_str(enum xe_force_wake_domain_id id);
+
+#define for_each_fw_domain_masked(domain__, mask__, fw__, tmp__) \
+       for (tmp__ = (mask__); tmp__; tmp__ &= ~BIT(ffs(tmp__) - 1)) \
+               for_each_if(((domain__) = ((fw__)->domains + \
+                                        (ffs(tmp__) - 1))) && \
+                                        (domain__)->reg_ctl.addr)
+
+#define for_each_fw_domain(domain__, fw__, tmp__) \
+       for_each_fw_domain_masked((domain__), (fw__)->initialized_domains, (fw__), (tmp__))
+
 static inline int
 xe_force_wake_ref(struct xe_force_wake *fw,
                  enum xe_force_wake_domains domain)
index 94d3403ec11ed3db8f181498f822fb15a7470a2d..4a2d9edb6a4c0e448fe3519122e479a1bea7f247 100644 (file)
@@ -168,6 +168,24 @@ void xe_gt_idle_disable_pg(struct xe_gt *gt)
        xe_mmio_write32(&gt->mmio, POWERGATE_ENABLE, gtidle->powergate_enable);
 }
 
+static void force_wake_domains_show(struct xe_gt *gt, struct drm_printer *p)
+{
+       struct xe_force_wake_domain *domain;
+       struct xe_force_wake *fw = gt_to_fw(gt);
+       unsigned int tmp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&fw->lock, flags);
+       for_each_fw_domain(domain, fw, tmp) {
+               drm_printf(p, "%s.ref_count=%u, %s.fwake=0x%x\n",
+                          xe_force_wake_domain_to_str(domain->id),
+                          READ_ONCE(domain->ref),
+                          xe_force_wake_domain_to_str(domain->id),
+                          xe_mmio_read32(&gt->mmio, domain->reg_ctl));
+       }
+       spin_unlock_irqrestore(&fw->lock, flags);
+}
+
 /**
  * xe_gt_idle_pg_print - Xe powergating info
  * @gt: GT object
@@ -259,6 +277,8 @@ int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p)
                           str_up_down(pg_status & GSC_AWAKE_STATUS));
        }
 
+       force_wake_domains_show(gt, p);
+
        return 0;
 }