drivers/gpu/drm/vc4/vc4_perfmon.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vc4/vc4_perfmon.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/vc4/vc4_perfmon.c
Extension
.c
Size
5270 bytes
Lines
249
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018 Broadcom
 */

/**
 * DOC: VC4 V3D performance monitor module
 *
 * The V3D block provides 16 hardware counters which can count various events.
 */

#include <drm/drm_print.h>

#include "vc4_drv.h"
#include "vc4_regs.h"

void vc4_perfmon_get(struct vc4_perfmon *perfmon)
{
	struct vc4_dev *vc4;

	if (!perfmon)
		return;

	vc4 = perfmon->dev;
	if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
		return;

	refcount_inc(&perfmon->refcnt);
}

void vc4_perfmon_put(struct vc4_perfmon *perfmon)
{
	struct vc4_dev *vc4;

	if (!perfmon)
		return;

	vc4 = perfmon->dev;
	if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
		return;

	if (refcount_dec_and_test(&perfmon->refcnt))
		kfree(perfmon);
}

void vc4_perfmon_start(struct vc4_dev *vc4, struct vc4_perfmon *perfmon)
{
	unsigned int i;
	u32 mask;

	if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
		return;

	if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon))
		return;

	for (i = 0; i < perfmon->ncounters; i++)
		V3D_WRITE(V3D_PCTRS(i), perfmon->events[i]);

	mask = GENMASK(perfmon->ncounters - 1, 0);
	V3D_WRITE(V3D_PCTRC, mask);
	V3D_WRITE(V3D_PCTRE, V3D_PCTRE_EN | mask);
	vc4->active_perfmon = perfmon;
}

void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon,
		      bool capture)
{
	unsigned int i;

	if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
		return;

	if (WARN_ON_ONCE(!vc4->active_perfmon ||
			 perfmon != vc4->active_perfmon))
		return;

	if (capture) {
		for (i = 0; i < perfmon->ncounters; i++)
			perfmon->counters[i] += V3D_READ(V3D_PCTR(i));
	}

	V3D_WRITE(V3D_PCTRE, 0);
	vc4->active_perfmon = NULL;
}

struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id)
{
	struct vc4_dev *vc4 = vc4file->dev;
	struct vc4_perfmon *perfmon;

Annotation

Implementation Notes