162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * SPDX-License-Identifier: MIT 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright © 2017-2018 Intel Corporation 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __I915_PMU_H__ 862306a36Sopenharmony_ci#define __I915_PMU_H__ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/hrtimer.h> 1162306a36Sopenharmony_ci#include <linux/perf_event.h> 1262306a36Sopenharmony_ci#include <linux/spinlock_types.h> 1362306a36Sopenharmony_ci#include <uapi/drm/i915_drm.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct drm_i915_private; 1662306a36Sopenharmony_cistruct intel_gt; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * Non-engine events that we need to track enabled-disabled transition and 2062306a36Sopenharmony_ci * current state. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_cienum i915_pmu_tracked_events { 2362306a36Sopenharmony_ci __I915_PMU_ACTUAL_FREQUENCY_ENABLED = 0, 2462306a36Sopenharmony_ci __I915_PMU_REQUESTED_FREQUENCY_ENABLED, 2562306a36Sopenharmony_ci __I915_PMU_RC6_RESIDENCY_ENABLED, 2662306a36Sopenharmony_ci __I915_PMU_TRACKED_EVENT_COUNT, /* count marker */ 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * Slots used from the sampling timer (non-engine events) with some extras for 3162306a36Sopenharmony_ci * convenience. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_cienum { 3462306a36Sopenharmony_ci __I915_SAMPLE_FREQ_ACT = 0, 3562306a36Sopenharmony_ci __I915_SAMPLE_FREQ_REQ, 3662306a36Sopenharmony_ci __I915_SAMPLE_RC6, 3762306a36Sopenharmony_ci __I915_SAMPLE_RC6_LAST_REPORTED, 3862306a36Sopenharmony_ci __I915_NUM_PMU_SAMPLERS 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define I915_PMU_MAX_GT 2 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* 4462306a36Sopenharmony_ci * How many different events we track in the global PMU mask. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * It is also used to know to needed number of event reference counters. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci#define I915_PMU_MASK_BITS \ 4962306a36Sopenharmony_ci (I915_ENGINE_SAMPLE_COUNT + \ 5062306a36Sopenharmony_ci I915_PMU_MAX_GT * __I915_PMU_TRACKED_EVENT_COUNT) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define I915_ENGINE_SAMPLE_COUNT (I915_SAMPLE_SEMA + 1) 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistruct i915_pmu_sample { 5562306a36Sopenharmony_ci u64 cur; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct i915_pmu { 5962306a36Sopenharmony_ci /** 6062306a36Sopenharmony_ci * @cpuhp: Struct used for CPU hotplug handling. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_ci struct { 6362306a36Sopenharmony_ci struct hlist_node node; 6462306a36Sopenharmony_ci unsigned int cpu; 6562306a36Sopenharmony_ci } cpuhp; 6662306a36Sopenharmony_ci /** 6762306a36Sopenharmony_ci * @base: PMU base. 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_ci struct pmu base; 7062306a36Sopenharmony_ci /** 7162306a36Sopenharmony_ci * @closed: i915 is unregistering. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci bool closed; 7462306a36Sopenharmony_ci /** 7562306a36Sopenharmony_ci * @name: Name as registered with perf core. 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci const char *name; 7862306a36Sopenharmony_ci /** 7962306a36Sopenharmony_ci * @lock: Lock protecting enable mask and ref count handling. 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci spinlock_t lock; 8262306a36Sopenharmony_ci /** 8362306a36Sopenharmony_ci * @unparked: GT unparked mask. 8462306a36Sopenharmony_ci */ 8562306a36Sopenharmony_ci unsigned int unparked; 8662306a36Sopenharmony_ci /** 8762306a36Sopenharmony_ci * @timer: Timer for internal i915 PMU sampling. 8862306a36Sopenharmony_ci */ 8962306a36Sopenharmony_ci struct hrtimer timer; 9062306a36Sopenharmony_ci /** 9162306a36Sopenharmony_ci * @enable: Bitmask of specific enabled events. 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * For some events we need to track their state and do some internal 9462306a36Sopenharmony_ci * house keeping. 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * Each engine event sampler type and event listed in enum 9762306a36Sopenharmony_ci * i915_pmu_tracked_events gets a bit in this field. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * Low bits are engine samplers and other events continue from there. 10062306a36Sopenharmony_ci */ 10162306a36Sopenharmony_ci u32 enable; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /** 10462306a36Sopenharmony_ci * @timer_last: 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * Timestmap of the previous timer invocation. 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_ci ktime_t timer_last; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /** 11162306a36Sopenharmony_ci * @enable_count: Reference counts for the enabled events. 11262306a36Sopenharmony_ci * 11362306a36Sopenharmony_ci * Array indices are mapped in the same way as bits in the @enable field 11462306a36Sopenharmony_ci * and they are used to control sampling on/off when multiple clients 11562306a36Sopenharmony_ci * are using the PMU API. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ci unsigned int enable_count[I915_PMU_MASK_BITS]; 11862306a36Sopenharmony_ci /** 11962306a36Sopenharmony_ci * @timer_enabled: Should the internal sampling timer be running. 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ci bool timer_enabled; 12262306a36Sopenharmony_ci /** 12362306a36Sopenharmony_ci * @sample: Current and previous (raw) counters for sampling events. 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * These counters are updated from the i915 PMU sampling timer. 12662306a36Sopenharmony_ci * 12762306a36Sopenharmony_ci * Only global counters are held here, while the per-engine ones are in 12862306a36Sopenharmony_ci * struct intel_engine_cs. 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci struct i915_pmu_sample sample[I915_PMU_MAX_GT][__I915_NUM_PMU_SAMPLERS]; 13162306a36Sopenharmony_ci /** 13262306a36Sopenharmony_ci * @sleep_last: Last time GT parked for RC6 estimation. 13362306a36Sopenharmony_ci */ 13462306a36Sopenharmony_ci ktime_t sleep_last[I915_PMU_MAX_GT]; 13562306a36Sopenharmony_ci /** 13662306a36Sopenharmony_ci * @irq_count: Number of interrupts 13762306a36Sopenharmony_ci * 13862306a36Sopenharmony_ci * Intentionally unsigned long to avoid atomics or heuristics on 32bit. 13962306a36Sopenharmony_ci * 4e9 interrupts are a lot and postprocessing can really deal with an 14062306a36Sopenharmony_ci * occasional wraparound easily. It's 32bit after all. 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_ci unsigned long irq_count; 14362306a36Sopenharmony_ci /** 14462306a36Sopenharmony_ci * @events_attr_group: Device events attribute group. 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ci struct attribute_group events_attr_group; 14762306a36Sopenharmony_ci /** 14862306a36Sopenharmony_ci * @i915_attr: Memory block holding device attributes. 14962306a36Sopenharmony_ci */ 15062306a36Sopenharmony_ci void *i915_attr; 15162306a36Sopenharmony_ci /** 15262306a36Sopenharmony_ci * @pmu_attr: Memory block holding device attributes. 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_ci void *pmu_attr; 15562306a36Sopenharmony_ci}; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci#ifdef CONFIG_PERF_EVENTS 15862306a36Sopenharmony_ciint i915_pmu_init(void); 15962306a36Sopenharmony_civoid i915_pmu_exit(void); 16062306a36Sopenharmony_civoid i915_pmu_register(struct drm_i915_private *i915); 16162306a36Sopenharmony_civoid i915_pmu_unregister(struct drm_i915_private *i915); 16262306a36Sopenharmony_civoid i915_pmu_gt_parked(struct intel_gt *gt); 16362306a36Sopenharmony_civoid i915_pmu_gt_unparked(struct intel_gt *gt); 16462306a36Sopenharmony_ci#else 16562306a36Sopenharmony_cistatic inline int i915_pmu_init(void) { return 0; } 16662306a36Sopenharmony_cistatic inline void i915_pmu_exit(void) {} 16762306a36Sopenharmony_cistatic inline void i915_pmu_register(struct drm_i915_private *i915) {} 16862306a36Sopenharmony_cistatic inline void i915_pmu_unregister(struct drm_i915_private *i915) {} 16962306a36Sopenharmony_cistatic inline void i915_pmu_gt_parked(struct intel_gt *gt) {} 17062306a36Sopenharmony_cistatic inline void i915_pmu_gt_unparked(struct intel_gt *gt) {} 17162306a36Sopenharmony_ci#endif 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#endif 174