Path: blob/21.2-virgl/src/etnaviv/drm/etnaviv_perfmon.c
4564 views
/*1* Copyright (C) 2017 Etnaviv Project2* Copyright (C) 2017 Zodiac Inflight Innovations3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23* Authors:24* Christian Gmeiner <[email protected]>25*/2627#include "etnaviv_priv.h"2829static int etna_perfmon_query_signals(struct etna_perfmon *pm, struct etna_perfmon_domain *dom)30{31struct etna_device *dev = pm->pipe->gpu->dev;32struct drm_etnaviv_pm_signal req = {33.pipe = pm->pipe->id,34.domain = dom->id35};3637do {38struct etna_perfmon_signal *sig;39int ret;4041ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_SIG, &req, sizeof(req));42if (ret)43break;4445sig = calloc(1, sizeof(*sig));46if (!sig)47return -ENOMEM;4849DEBUG_MSG("perfmon signal:");50DEBUG_MSG("id = %d", req.id);51DEBUG_MSG("name = %s", req.name);5253sig->domain = dom;54sig->signal = req.id;55strncpy(sig->name, req.name, sizeof(sig->name));56list_addtail(&sig->head, &dom->signals);57} while (req.iter != 0xffff);5859return 0;60}6162static int etna_perfmon_query_domains(struct etna_perfmon *pm)63{64struct etna_device *dev = pm->pipe->gpu->dev;65struct drm_etnaviv_pm_domain req = {66.pipe = pm->pipe->id67};6869do {70struct etna_perfmon_domain *dom;71int ret;7273ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_DOM, &req, sizeof(req));74if (ret)75break;7677dom = calloc(1, sizeof(*dom));78if (!dom)79return -ENOMEM;8081list_inithead(&dom->signals);82dom->id = req.id;83strncpy(dom->name, req.name, sizeof(dom->name));84list_addtail(&dom->head, &pm->domains);8586DEBUG_MSG("perfmon domain:");87DEBUG_MSG("id = %d", req.id);88DEBUG_MSG("name = %s", req.name);89DEBUG_MSG("nr_signals = %d", req.nr_signals);9091/* Query all available signals for this domain. */92if (req.nr_signals > 0) {93ret = etna_perfmon_query_signals(pm, dom);94if (ret)95return ret;96}97} while (req.iter != 0xff);9899return 0;100}101102static void etna_perfmon_free_signals(struct etna_perfmon_domain *dom)103{104struct etna_perfmon_signal *sig, *next;105106LIST_FOR_EACH_ENTRY_SAFE(sig, next, &dom->signals, head) {107list_del(&sig->head);108free(sig);109}110}111112static void etna_perfmon_free_domains(struct etna_perfmon *pm)113{114struct etna_perfmon_domain *dom, *next;115116LIST_FOR_EACH_ENTRY_SAFE(dom, next, &pm->domains, head) {117etna_perfmon_free_signals(dom);118list_del(&dom->head);119free(dom);120}121}122123struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe)124{125struct etna_perfmon *pm;126int ret;127128pm = calloc(1, sizeof(*pm));129if (!pm) {130ERROR_MSG("allocation failed");131return NULL;132}133134list_inithead(&pm->domains);135pm->pipe = pipe;136137/* query all available domains and sources for this device */138ret = etna_perfmon_query_domains(pm);139if (ret)140goto fail;141142return pm;143144fail:145etna_perfmon_del(pm);146return NULL;147}148149void etna_perfmon_del(struct etna_perfmon *pm)150{151if (!pm)152return;153154etna_perfmon_free_domains(pm);155free(pm);156}157158struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name)159{160struct etna_perfmon_domain *dom;161162if (pm) {163LIST_FOR_EACH_ENTRY(dom, &pm->domains, head) {164if (!strcmp(dom->name, name))165return dom;166}167}168169return NULL;170}171172struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name)173{174struct etna_perfmon_signal *signal;175176if (dom) {177LIST_FOR_EACH_ENTRY(signal, &dom->signals, head) {178if (!strcmp(signal->name, name))179return signal;180}181}182183return NULL;184}185186187