Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a827e456 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Account for fixed perfcounter groups



Most performance counter groups have general purpose counters that
can be programmed to any number of countable types. That said
some groups have counters with fixed countables. When reserving those
groups the countable is equal to the register - so when you ask for
countable 0 in VBIF_PWR for example it is expected that will always
match to a certain register. Add a flag member to the perfcounter
group and declare PWR and VBIF_PWR as fixed groups and handle them
accordingly in adreno_perfcounter_get() so that the correct register
is returned.

CRs-fixed: 582739
Change-Id: Ic0dedbad271c7472efce5f79e9055b7b3d224d17
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent d96f7618
Loading
Loading
Loading
Loading
+46 −19
Original line number Diff line number Diff line
@@ -602,6 +602,18 @@ int adreno_perfcounter_query_group(struct adreno_device *adreno_dev,
	return 0;
}

static inline void refcount_group(struct adreno_perfcount_group *group,
	unsigned int reg, unsigned int flags, unsigned int *lo)
{
	if (flags & PERFCOUNTER_FLAG_KERNEL)
		group->regs[reg].kernelcount++;
	else
		group->regs[reg].usercount++;

	if (lo)
		*lo = group->regs[reg].offset;
}

/**
 * adreno_perfcounter_get: Try to put a countable in an available counter
 * @adreno_dev: Adreno device to configure
@@ -621,7 +633,7 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
{
	struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
	struct adreno_perfcount_group *group;
	unsigned int i, empty = -1;
	unsigned int empty = -1;
	int ret = 0;

	/* always clear return variables */
@@ -636,21 +648,35 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,

	group = &(counters->groups[groupid]);

	if (group->flags & ADRENO_PERFCOUNTER_GROUP_FIXED) {
		/*
		 * In fixed groups the countable equals the fixed register the
		 * user wants. First make sure it is in range
		 */

		if (countable >= group->reg_count)
			return -EINVAL;

		/* If it is already reserved, just increase the refcounts */
		if ((group->regs[countable].kernelcount != 0) ||
			(group->regs[countable].usercount != 0)) {
				refcount_group(group, countable, flags, offset);
				return 0;
		}

		empty = countable;
	} else {
		unsigned int i;

		/*
		 * Check if the countable is already associated with a counter.
	 * Refcount and return the offset, otherwise, try and find an empty
	 * counter and assign the countable to it.
		 * Refcount and return the offset, otherwise, try and find an
		 * empty counter and assign the countable to it.
		 */

		for (i = 0; i < group->reg_count; i++) {
			if (group->regs[i].countable == countable) {
			/* Countable already associated with counter */
			if (flags & PERFCOUNTER_FLAG_KERNEL)
				group->regs[i].kernelcount++;
			else
				group->regs[i].usercount++;

			if (offset)
				*offset = group->regs[i].offset;
				refcount_group(group, i, flags, offset);
				return 0;
			} else if (group->regs[i].countable ==
			KGSL_PERFCOUNTER_NOT_USED) {
@@ -658,6 +684,7 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
				empty = i;
			}
		}
	}

	/* no available counters, so do nothing else */
	if (empty == -1)
+17 −2
Original line number Diff line number Diff line
@@ -242,8 +242,19 @@ struct adreno_perfcount_group {
	struct adreno_perfcount_register *regs;
	unsigned int reg_count;
	const char *name;
	unsigned long flags;
};

/*
 * ADRENO_PERFCOUNTER_GROUP_FIXED indicates that a perfcounter group is fixed -
 * instead of having configurable countables like the other groups, registers in
 * fixed groups have a hardwired countable.  So when the user requests a
 * countable in one of these groups, that countable should be used as the
 * register offset to return
 */

#define ADRENO_PERFCOUNTER_GROUP_FIXED BIT(0)

/**
 * adreno_perfcounts: all available perfcounter groups
 * @groups: available groups for this device
@@ -265,11 +276,15 @@ struct adreno_invalid_countables {
};

#define ADRENO_PERFCOUNTER_GROUP(core, name) { core##_perfcounters_##name, \
	ARRAY_SIZE(core##_perfcounters_##name), __stringify(name) }
	ARRAY_SIZE(core##_perfcounters_##name), __stringify(name), 0 }

#define ADRENO_PERFCOUNTER_GROUP_FLAGS(core, name, flags) \
	{ core##_perfcounters_##name, \
	ARRAY_SIZE(core##_perfcounters_##name), __stringify(name), flags }

#define ADRENO_PERFCOUNTER_GROUP_OFF(core, name, offset) \
	[KGSL_PERFCOUNTER_GROUP_##offset] = { core##_perfcounters_##name, \
	ARRAY_SIZE(core##_perfcounters_##name), __stringify(name) }
	ARRAY_SIZE(core##_perfcounters_##name), __stringify(name), 0 }

#define ADRENO_PERFCOUNTER_INVALID_COUNTABLE(name, off) \
	[KGSL_PERFCOUNTER_GROUP_##off] = { name##_invalid_countables, \
+4 −2
Original line number Diff line number Diff line
@@ -1807,9 +1807,11 @@ static struct adreno_perfcount_group a3xx_perfcounter_groups[] = {
	ADRENO_PERFCOUNTER_GROUP(a3xx, tp),
	ADRENO_PERFCOUNTER_GROUP(a3xx, sp),
	ADRENO_PERFCOUNTER_GROUP(a3xx, rb),
	ADRENO_PERFCOUNTER_GROUP(a3xx, pwr),
	ADRENO_PERFCOUNTER_GROUP_FLAGS(a3xx, pwr,
		ADRENO_PERFCOUNTER_GROUP_FIXED),
	ADRENO_PERFCOUNTER_GROUP(a3xx, vbif),
	ADRENO_PERFCOUNTER_GROUP(a3xx, vbif_pwr),
	ADRENO_PERFCOUNTER_GROUP_FLAGS(a3xx, vbif_pwr,
		ADRENO_PERFCOUNTER_GROUP_FIXED),
};

static struct adreno_perfcounters a3xx_perfcounters = {