Commit 91be6115 authored by Vinay Belgaumkar's avatar Vinay Belgaumkar
Browse files

drm/xe: Add forcewake status to powergate_info



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: default avatarBadal Nilawar <badal.nilawar@intel.com>
Signed-off-by: default avatarVinay <Belgaumkar&lt;vinay.belgaumkar@intel.com>
Link: https://patch.msgid.link/20260204190314.2904009-3-vinay.belgaumkar@intel.com
parent 2ea05b4b
Loading
Loading
Loading
Loading
+40 −6
Original line number Diff line number Diff line
@@ -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";
	}
}
+11 −0
Original line number Diff line number Diff line
@@ -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)
+20 −0
Original line number Diff line number Diff line
@@ -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;
}