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

Commit 9c6c4593 authored by Christian Gmeiner's avatar Christian Gmeiner Committed by Greg Kroah-Hartman
Browse files

drm/etnaviv: rework perfmon query infrastructure



commit ed1dd899baa32d47d9a93d98336472da50564346 upstream.

Report the correct perfmon domains and signals depending
on the supported feature flags.

Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Fixes: 9e2c2e27 ("drm/etnaviv: add infrastructure to query perf counter")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarChristian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 23599f81
Loading
Loading
Loading
Loading
+53 −7
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Copyright (C) 2017 Zodiac Inflight Innovations
 */

#include "common.xml.h"
#include "etnaviv_gpu.h"
#include "etnaviv_perfmon.h"
#include "state_hi.xml.h"
@@ -31,6 +32,7 @@ struct etnaviv_pm_domain {
};

struct etnaviv_pm_domain_meta {
	unsigned int feature;
	const struct etnaviv_pm_domain *domains;
	u32 nr_domains;
};
@@ -388,36 +390,78 @@ static const struct etnaviv_pm_domain doms_vg[] = {

static const struct etnaviv_pm_domain_meta doms_meta[] = {
	{
		.feature = chipFeatures_PIPE_3D,
		.nr_domains = ARRAY_SIZE(doms_3d),
		.domains = &doms_3d[0]
	},
	{
		.feature = chipFeatures_PIPE_2D,
		.nr_domains = ARRAY_SIZE(doms_2d),
		.domains = &doms_2d[0]
	},
	{
		.feature = chipFeatures_PIPE_VG,
		.nr_domains = ARRAY_SIZE(doms_vg),
		.domains = &doms_vg[0]
	}
};

static unsigned int num_pm_domains(const struct etnaviv_gpu *gpu)
{
	unsigned int num = 0, i;

	for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
		const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];

		if (gpu->identity.features & meta->feature)
			num += meta->nr_domains;
	}

	return num;
}

static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu,
	unsigned int index)
{
	const struct etnaviv_pm_domain *domain = NULL;
	unsigned int offset = 0, i;

	for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
		const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];

		if (!(gpu->identity.features & meta->feature))
			continue;

		if (meta->nr_domains < (index - offset)) {
			offset += meta->nr_domains;
			continue;
		}

		domain = meta->domains + (index - offset);
	}

	return domain;
}

int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
	struct drm_etnaviv_pm_domain *domain)
{
	const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe];
	const unsigned int nr_domains = num_pm_domains(gpu);
	const struct etnaviv_pm_domain *dom;

	if (domain->iter >= meta->nr_domains)
	if (domain->iter >= nr_domains)
		return -EINVAL;

	dom = meta->domains + domain->iter;
	dom = pm_domain(gpu, domain->iter);
	if (!dom)
		return -EINVAL;

	domain->id = domain->iter;
	domain->nr_signals = dom->nr_signals;
	strncpy(domain->name, dom->name, sizeof(domain->name));

	domain->iter++;
	if (domain->iter == meta->nr_domains)
	if (domain->iter == nr_domains)
		domain->iter = 0xff;

	return 0;
@@ -426,14 +470,16 @@ int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
	struct drm_etnaviv_pm_signal *signal)
{
	const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe];
	const unsigned int nr_domains = num_pm_domains(gpu);
	const struct etnaviv_pm_domain *dom;
	const struct etnaviv_pm_signal *sig;

	if (signal->domain >= meta->nr_domains)
	if (signal->domain >= nr_domains)
		return -EINVAL;

	dom = meta->domains + signal->domain;
	dom = pm_domain(gpu, signal->domain);
	if (!dom)
		return -EINVAL;

	if (signal->iter >= dom->nr_signals)
		return -EINVAL;