drm/etnaviv: rework perfmon query infrastructure
Report the correct perfmon domains and signals depending
on the supported feature flags.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Fixes: 9e2c2e2730
("drm/etnaviv: add infrastructure to query perf counter")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
This commit is contained in:
parent
f56f1579a0
commit
ed1dd899ba
@ -32,6 +32,7 @@ struct etnaviv_pm_domain {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct etnaviv_pm_domain_meta {
|
struct etnaviv_pm_domain_meta {
|
||||||
|
unsigned int feature;
|
||||||
const struct etnaviv_pm_domain *domains;
|
const struct etnaviv_pm_domain *domains;
|
||||||
u32 nr_domains;
|
u32 nr_domains;
|
||||||
};
|
};
|
||||||
@ -410,36 +411,78 @@ static const struct etnaviv_pm_domain doms_vg[] = {
|
|||||||
|
|
||||||
static const struct etnaviv_pm_domain_meta doms_meta[] = {
|
static const struct etnaviv_pm_domain_meta doms_meta[] = {
|
||||||
{
|
{
|
||||||
|
.feature = chipFeatures_PIPE_3D,
|
||||||
.nr_domains = ARRAY_SIZE(doms_3d),
|
.nr_domains = ARRAY_SIZE(doms_3d),
|
||||||
.domains = &doms_3d[0]
|
.domains = &doms_3d[0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
.feature = chipFeatures_PIPE_2D,
|
||||||
.nr_domains = ARRAY_SIZE(doms_2d),
|
.nr_domains = ARRAY_SIZE(doms_2d),
|
||||||
.domains = &doms_2d[0]
|
.domains = &doms_2d[0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
.feature = chipFeatures_PIPE_VG,
|
||||||
.nr_domains = ARRAY_SIZE(doms_vg),
|
.nr_domains = ARRAY_SIZE(doms_vg),
|
||||||
.domains = &doms_vg[0]
|
.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,
|
int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
|
||||||
struct drm_etnaviv_pm_domain *domain)
|
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;
|
const struct etnaviv_pm_domain *dom;
|
||||||
|
|
||||||
if (domain->iter >= meta->nr_domains)
|
if (domain->iter >= nr_domains)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dom = meta->domains + domain->iter;
|
dom = pm_domain(gpu, domain->iter);
|
||||||
|
if (!dom)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
domain->id = domain->iter;
|
domain->id = domain->iter;
|
||||||
domain->nr_signals = dom->nr_signals;
|
domain->nr_signals = dom->nr_signals;
|
||||||
strncpy(domain->name, dom->name, sizeof(domain->name));
|
strncpy(domain->name, dom->name, sizeof(domain->name));
|
||||||
|
|
||||||
domain->iter++;
|
domain->iter++;
|
||||||
if (domain->iter == meta->nr_domains)
|
if (domain->iter == nr_domains)
|
||||||
domain->iter = 0xff;
|
domain->iter = 0xff;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -448,14 +491,16 @@ int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
|
|||||||
int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
|
int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
|
||||||
struct drm_etnaviv_pm_signal *signal)
|
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_domain *dom;
|
||||||
const struct etnaviv_pm_signal *sig;
|
const struct etnaviv_pm_signal *sig;
|
||||||
|
|
||||||
if (signal->domain >= meta->nr_domains)
|
if (signal->domain >= nr_domains)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dom = meta->domains + signal->domain;
|
dom = pm_domain(gpu, signal->domain);
|
||||||
|
if (!dom)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (signal->iter >= dom->nr_signals)
|
if (signal->iter >= dom->nr_signals)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
Loading…
Reference in New Issue
Block a user