xref: /openbmc/linux/drivers/gpu/drm/i915/i915_pmu.h (revision 0791faebfe750292a8a842b64795a390ca4a3b51)
1b46a33e2STvrtko Ursulin /*
2058a9b43SMichal Wajdeczko  * SPDX-License-Identifier: MIT
3b46a33e2STvrtko Ursulin  *
4058a9b43SMichal Wajdeczko  * Copyright © 2017-2018 Intel Corporation
5b46a33e2STvrtko Ursulin  */
6058a9b43SMichal Wajdeczko 
7b46a33e2STvrtko Ursulin #ifndef __I915_PMU_H__
8b46a33e2STvrtko Ursulin #define __I915_PMU_H__
9b46a33e2STvrtko Ursulin 
10058a9b43SMichal Wajdeczko #include <linux/hrtimer.h>
11058a9b43SMichal Wajdeczko #include <linux/perf_event.h>
12058a9b43SMichal Wajdeczko #include <linux/spinlock_types.h>
1383d2bdb6SJani Nikula #include <uapi/drm/i915_drm.h>
14058a9b43SMichal Wajdeczko 
15058a9b43SMichal Wajdeczko struct drm_i915_private;
16da5d5167STvrtko Ursulin struct intel_gt;
17058a9b43SMichal Wajdeczko 
187bc30374SJani Nikula /*
19348fb0cbSTvrtko Ursulin  * Non-engine events that we need to track enabled-disabled transition and
20348fb0cbSTvrtko Ursulin  * current state.
21348fb0cbSTvrtko Ursulin  */
22348fb0cbSTvrtko Ursulin enum i915_pmu_tracked_events {
23348fb0cbSTvrtko Ursulin 	__I915_PMU_ACTUAL_FREQUENCY_ENABLED = 0,
24348fb0cbSTvrtko Ursulin 	__I915_PMU_REQUESTED_FREQUENCY_ENABLED,
25348fb0cbSTvrtko Ursulin 	__I915_PMU_RC6_RESIDENCY_ENABLED,
26348fb0cbSTvrtko Ursulin 	__I915_PMU_TRACKED_EVENT_COUNT, /* count marker */
27348fb0cbSTvrtko Ursulin };
28348fb0cbSTvrtko Ursulin 
297bc30374SJani Nikula /*
30348fb0cbSTvrtko Ursulin  * Slots used from the sampling timer (non-engine events) with some extras for
31348fb0cbSTvrtko Ursulin  * convenience.
32348fb0cbSTvrtko Ursulin  */
33b46a33e2STvrtko Ursulin enum {
34b46a33e2STvrtko Ursulin 	__I915_SAMPLE_FREQ_ACT = 0,
35b46a33e2STvrtko Ursulin 	__I915_SAMPLE_FREQ_REQ,
361fe699e3STvrtko Ursulin 	__I915_SAMPLE_RC6,
37df6a4205STvrtko Ursulin 	__I915_SAMPLE_RC6_LAST_REPORTED,
38b46a33e2STvrtko Ursulin 	__I915_NUM_PMU_SAMPLERS
39b46a33e2STvrtko Ursulin };
40b46a33e2STvrtko Ursulin 
41*419491eaSMatt Atwood #define I915_PMU_MAX_GT 2
42bc4be0a3STvrtko Ursulin 
437bc30374SJani Nikula /*
44b46a33e2STvrtko Ursulin  * How many different events we track in the global PMU mask.
45b46a33e2STvrtko Ursulin  *
46b46a33e2STvrtko Ursulin  * It is also used to know to needed number of event reference counters.
47b46a33e2STvrtko Ursulin  */
48b46a33e2STvrtko Ursulin #define I915_PMU_MASK_BITS \
49bc4be0a3STvrtko Ursulin 	(I915_ENGINE_SAMPLE_COUNT + \
50*419491eaSMatt Atwood 	 I915_PMU_MAX_GT * __I915_PMU_TRACKED_EVENT_COUNT)
51b46a33e2STvrtko Ursulin 
52d8b879bbSTvrtko Ursulin #define I915_ENGINE_SAMPLE_COUNT (I915_SAMPLE_SEMA + 1)
53d8b879bbSTvrtko Ursulin 
54b46a33e2STvrtko Ursulin struct i915_pmu_sample {
55b46a33e2STvrtko Ursulin 	u64 cur;
56b46a33e2STvrtko Ursulin };
57b46a33e2STvrtko Ursulin 
58b46a33e2STvrtko Ursulin struct i915_pmu {
59b46a33e2STvrtko Ursulin 	/**
60f5a179d4SMichał Winiarski 	 * @cpuhp: Struct used for CPU hotplug handling.
61b46a33e2STvrtko Ursulin 	 */
62f5a179d4SMichał Winiarski 	struct {
63b46a33e2STvrtko Ursulin 		struct hlist_node node;
64537f9c84STvrtko Ursulin 		unsigned int cpu;
65f5a179d4SMichał Winiarski 	} cpuhp;
66b46a33e2STvrtko Ursulin 	/**
67b46a33e2STvrtko Ursulin 	 * @base: PMU base.
68b46a33e2STvrtko Ursulin 	 */
69b46a33e2STvrtko Ursulin 	struct pmu base;
70b46a33e2STvrtko Ursulin 	/**
71b00bccb3STvrtko Ursulin 	 * @closed: i915 is unregistering.
72b00bccb3STvrtko Ursulin 	 */
73b00bccb3STvrtko Ursulin 	bool closed;
74b00bccb3STvrtko Ursulin 	/**
7505488673STvrtko Ursulin 	 * @name: Name as registered with perf core.
7605488673STvrtko Ursulin 	 */
7705488673STvrtko Ursulin 	const char *name;
7805488673STvrtko Ursulin 	/**
79b46a33e2STvrtko Ursulin 	 * @lock: Lock protecting enable mask and ref count handling.
80b46a33e2STvrtko Ursulin 	 */
81b46a33e2STvrtko Ursulin 	spinlock_t lock;
82b46a33e2STvrtko Ursulin 	/**
83b319cc59STvrtko Ursulin 	 * @unparked: GT unparked mask.
84b319cc59STvrtko Ursulin 	 */
85b319cc59STvrtko Ursulin 	unsigned int unparked;
86b319cc59STvrtko Ursulin 	/**
87b46a33e2STvrtko Ursulin 	 * @timer: Timer for internal i915 PMU sampling.
88b46a33e2STvrtko Ursulin 	 */
89b46a33e2STvrtko Ursulin 	struct hrtimer timer;
90b46a33e2STvrtko Ursulin 	/**
91348fb0cbSTvrtko Ursulin 	 * @enable: Bitmask of specific enabled events.
92b46a33e2STvrtko Ursulin 	 *
93348fb0cbSTvrtko Ursulin 	 * For some events we need to track their state and do some internal
94348fb0cbSTvrtko Ursulin 	 * house keeping.
95b46a33e2STvrtko Ursulin 	 *
96348fb0cbSTvrtko Ursulin 	 * Each engine event sampler type and event listed in enum
97348fb0cbSTvrtko Ursulin 	 * i915_pmu_tracked_events gets a bit in this field.
98348fb0cbSTvrtko Ursulin 	 *
99348fb0cbSTvrtko Ursulin 	 * Low bits are engine samplers and other events continue from there.
100b46a33e2STvrtko Ursulin 	 */
101348fb0cbSTvrtko Ursulin 	u32 enable;
1029f473ecfSTvrtko Ursulin 
1039f473ecfSTvrtko Ursulin 	/**
1049f473ecfSTvrtko Ursulin 	 * @timer_last:
1059f473ecfSTvrtko Ursulin 	 *
1069f473ecfSTvrtko Ursulin 	 * Timestmap of the previous timer invocation.
1079f473ecfSTvrtko Ursulin 	 */
1089f473ecfSTvrtko Ursulin 	ktime_t timer_last;
1099f473ecfSTvrtko Ursulin 
110b46a33e2STvrtko Ursulin 	/**
111b46a33e2STvrtko Ursulin 	 * @enable_count: Reference counts for the enabled events.
112b46a33e2STvrtko Ursulin 	 *
113b46a33e2STvrtko Ursulin 	 * Array indices are mapped in the same way as bits in the @enable field
114b46a33e2STvrtko Ursulin 	 * and they are used to control sampling on/off when multiple clients
115b46a33e2STvrtko Ursulin 	 * are using the PMU API.
116b46a33e2STvrtko Ursulin 	 */
117b46a33e2STvrtko Ursulin 	unsigned int enable_count[I915_PMU_MASK_BITS];
118b46a33e2STvrtko Ursulin 	/**
119feff0dc6STvrtko Ursulin 	 * @timer_enabled: Should the internal sampling timer be running.
120feff0dc6STvrtko Ursulin 	 */
121feff0dc6STvrtko Ursulin 	bool timer_enabled;
122feff0dc6STvrtko Ursulin 	/**
123b46a33e2STvrtko Ursulin 	 * @sample: Current and previous (raw) counters for sampling events.
124b46a33e2STvrtko Ursulin 	 *
125b46a33e2STvrtko Ursulin 	 * These counters are updated from the i915 PMU sampling timer.
126b46a33e2STvrtko Ursulin 	 *
127b46a33e2STvrtko Ursulin 	 * Only global counters are held here, while the per-engine ones are in
128b46a33e2STvrtko Ursulin 	 * struct intel_engine_cs.
129b46a33e2STvrtko Ursulin 	 */
130*419491eaSMatt Atwood 	struct i915_pmu_sample sample[I915_PMU_MAX_GT][__I915_NUM_PMU_SAMPLERS];
131109ec558STvrtko Ursulin 	/**
13216ffe73cSChris Wilson 	 * @sleep_last: Last time GT parked for RC6 estimation.
1331fe699e3STvrtko Ursulin 	 */
134*419491eaSMatt Atwood 	ktime_t sleep_last[I915_PMU_MAX_GT];
1351fe699e3STvrtko Ursulin 	/**
1369c6508b9SThomas Gleixner 	 * @irq_count: Number of interrupts
1379c6508b9SThomas Gleixner 	 *
1389c6508b9SThomas Gleixner 	 * Intentionally unsigned long to avoid atomics or heuristics on 32bit.
1399c6508b9SThomas Gleixner 	 * 4e9 interrupts are a lot and postprocessing can really deal with an
1409c6508b9SThomas Gleixner 	 * occasional wraparound easily. It's 32bit after all.
1419c6508b9SThomas Gleixner 	 */
1429c6508b9SThomas Gleixner 	unsigned long irq_count;
1439c6508b9SThomas Gleixner 	/**
14446129dc1SMichał Winiarski 	 * @events_attr_group: Device events attribute group.
14546129dc1SMichał Winiarski 	 */
14646129dc1SMichał Winiarski 	struct attribute_group events_attr_group;
14746129dc1SMichał Winiarski 	/**
148109ec558STvrtko Ursulin 	 * @i915_attr: Memory block holding device attributes.
149109ec558STvrtko Ursulin 	 */
150109ec558STvrtko Ursulin 	void *i915_attr;
151109ec558STvrtko Ursulin 	/**
152109ec558STvrtko Ursulin 	 * @pmu_attr: Memory block holding device attributes.
153109ec558STvrtko Ursulin 	 */
154109ec558STvrtko Ursulin 	void *pmu_attr;
155b46a33e2STvrtko Ursulin };
156b46a33e2STvrtko Ursulin 
157b46a33e2STvrtko Ursulin #ifdef CONFIG_PERF_EVENTS
158a04ea6aeSJason Ekstrand int i915_pmu_init(void);
159537f9c84STvrtko Ursulin void i915_pmu_exit(void);
160b46a33e2STvrtko Ursulin void i915_pmu_register(struct drm_i915_private *i915);
161b46a33e2STvrtko Ursulin void i915_pmu_unregister(struct drm_i915_private *i915);
162da5d5167STvrtko Ursulin void i915_pmu_gt_parked(struct intel_gt *gt);
163da5d5167STvrtko Ursulin void i915_pmu_gt_unparked(struct intel_gt *gt);
164b46a33e2STvrtko Ursulin #else
i915_pmu_init(void)165a04ea6aeSJason Ekstrand static inline int i915_pmu_init(void) { return 0; }
i915_pmu_exit(void)166537f9c84STvrtko Ursulin static inline void i915_pmu_exit(void) {}
i915_pmu_register(struct drm_i915_private * i915)167b46a33e2STvrtko Ursulin static inline void i915_pmu_register(struct drm_i915_private *i915) {}
i915_pmu_unregister(struct drm_i915_private * i915)168b46a33e2STvrtko Ursulin static inline void i915_pmu_unregister(struct drm_i915_private *i915) {}
i915_pmu_gt_parked(struct intel_gt * gt)169da5d5167STvrtko Ursulin static inline void i915_pmu_gt_parked(struct intel_gt *gt) {}
i915_pmu_gt_unparked(struct intel_gt * gt)170da5d5167STvrtko Ursulin static inline void i915_pmu_gt_unparked(struct intel_gt *gt) {}
171b46a33e2STvrtko Ursulin #endif
172b46a33e2STvrtko Ursulin 
173b46a33e2STvrtko Ursulin #endif
174