lkml.org 
[lkml]   [2020]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 202/254] drm/etnaviv: rework perfmon query infrastructure
    Date
    From: Christian Gmeiner <christian.gmeiner@gmail.com>

    commit ed1dd899baa32d47d9a93d98336472da50564346 upstream.

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

    Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
    Fixes: 9e2c2e273012 ("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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 59 ++++++++++++++++++++++++++----
    1 file changed, 52 insertions(+), 7 deletions(-)

    --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
    +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
    @@ -32,6 +32,7 @@ struct etnaviv_pm_domain {
    };

    struct etnaviv_pm_domain_meta {
    + unsigned int feature;
    const struct etnaviv_pm_domain *domains;
    u32 nr_domains;
    };
    @@ -410,36 +411,78 @@ static const struct etnaviv_pm_domain do

    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;
    @@ -448,14 +491,16 @@ int etnaviv_pm_query_dom(struct etnaviv_
    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;

    \
     
     \ /
      Last update: 2020-04-16 16:29    [W:4.073 / U:0.280 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site