aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_pmu.c')
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 21eb0c5b320d..93fbf53578da 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -356,7 +356,7 @@ static bool exclusive_mmio_access(const struct drm_i915_private *i915)
return GRAPHICS_VER(i915) == 7;
}
-static void engine_sample(struct intel_engine_cs *engine, unsigned int period_ns)
+static void gen3_engine_sample(struct intel_engine_cs *engine, unsigned int period_ns)
{
struct intel_engine_pmu *pmu = &engine->pmu;
bool busy;
@@ -391,6 +391,31 @@ static void engine_sample(struct intel_engine_cs *engine, unsigned int period_ns
add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns);
}
+static void gen2_engine_sample(struct intel_engine_cs *engine, unsigned int period_ns)
+{
+ struct intel_engine_pmu *pmu = &engine->pmu;
+ u32 tail, head, acthd;
+
+ tail = ENGINE_READ_FW(engine, RING_TAIL);
+ head = ENGINE_READ_FW(engine, RING_HEAD);
+ acthd = ENGINE_READ_FW(engine, ACTHD);
+
+ if (head & HEAD_WAIT_I8XX)
+ add_sample(&pmu->sample[I915_SAMPLE_WAIT], period_ns);
+
+ if (head & HEAD_WAIT_I8XX || head != acthd ||
+ (head & HEAD_ADDR) != (tail & TAIL_ADDR))
+ add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns);
+}
+
+static void engine_sample(struct intel_engine_cs *engine, unsigned int period_ns)
+{
+ if (GRAPHICS_VER(engine->i915) >= 3)
+ gen3_engine_sample(engine, period_ns);
+ else
+ gen2_engine_sample(engine, period_ns);
+}
+
static void
engines_sample(struct intel_gt *gt, unsigned int period_ns)
{
@@ -834,15 +859,14 @@ static void i915_pmu_event_start(struct perf_event *event, int flags)
static void i915_pmu_event_stop(struct perf_event *event, int flags)
{
- struct drm_i915_private *i915 =
- container_of(event->pmu, typeof(*i915), pmu.base);
- struct i915_pmu *pmu = &i915->pmu;
+ struct i915_pmu *pmu = event_to_pmu(event);
if (pmu->closed)
goto out;
if (flags & PERF_EF_UPDATE)
i915_pmu_event_read(event);
+
i915_pmu_disable(event);
out:
@@ -1232,17 +1256,6 @@ static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu)
cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
}
-static bool is_igp(struct drm_i915_private *i915)
-{
- struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
-
- /* IGP is 0000:00:02.0 */
- return pci_domain_nr(pdev->bus) == 0 &&
- pdev->bus->number == 0 &&
- PCI_SLOT(pdev->devfn) == 2 &&
- PCI_FUNC(pdev->devfn) == 0;
-}
-
void i915_pmu_register(struct drm_i915_private *i915)
{
struct i915_pmu *pmu = &i915->pmu;
@@ -1255,18 +1268,13 @@ void i915_pmu_register(struct drm_i915_private *i915)
int ret = -ENOMEM;
- if (GRAPHICS_VER(i915) <= 2) {
- drm_info(&i915->drm, "PMU not supported for this GPU.");
- return;
- }
-
spin_lock_init(&pmu->lock);
hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
pmu->timer.function = i915_sample;
pmu->cpuhp.cpu = -1;
init_rc6(pmu);
- if (!is_igp(i915)) {
+ if (IS_DGFX(i915)) {
pmu->name = kasprintf(GFP_KERNEL,
"i915_%s",
dev_name(i915->drm.dev));
@@ -1318,7 +1326,7 @@ err_attr:
pmu->base.event_init = NULL;
free_event_attributes(pmu);
err_name:
- if (!is_igp(i915))
+ if (IS_DGFX(i915))
kfree(pmu->name);
err:
drm_notice(&i915->drm, "Failed to register PMU!\n");
@@ -1346,7 +1354,7 @@ void i915_pmu_unregister(struct drm_i915_private *i915)
perf_pmu_unregister(&pmu->base);
pmu->base.event_init = NULL;
kfree(pmu->base.attr_groups);
- if (!is_igp(i915))
+ if (IS_DGFX(i915))
kfree(pmu->name);
free_event_attributes(pmu);
}