2 * Copyright (C) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Christian Gmeiner <christian.gmeiner@gmail.com>
28 #include "etnaviv_priv.h"
30 static int etna_perfmon_query_signals(struct etna_perfmon *pm, struct etna_perfmon_domain *dom)
32 struct etna_device *dev = pm->pipe->gpu->dev;
33 struct drm_etnaviv_pm_signal req = {
39 struct etna_perfmon_signal *sig;
42 ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_SIG, &req, sizeof(req));
46 sig = calloc(1, sizeof(*sig));
50 INFO_MSG("perfmon signal:");
51 INFO_MSG("id = %d", req.id);
52 INFO_MSG("name = %s", req.name);
56 strncpy(sig->name, req.name, sizeof(sig->name));
57 list_addtail(&sig->head, &dom->signals);
58 } while (req.iter != 0xffff);
63 static int etna_perfmon_query_domains(struct etna_perfmon *pm)
65 struct etna_device *dev = pm->pipe->gpu->dev;
66 struct drm_etnaviv_pm_domain req = {
71 struct etna_perfmon_domain *dom;
74 ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_DOM, &req, sizeof(req));
78 dom = calloc(1, sizeof(*dom));
82 list_inithead(&dom->signals);
84 strncpy(dom->name, req.name, sizeof(dom->name));
85 list_addtail(&dom->head, &pm->domains);
87 INFO_MSG("perfmon domain:");
88 INFO_MSG("id = %d", req.id);
89 INFO_MSG("name = %s", req.name);
90 INFO_MSG("nr_signals = %d", req.nr_signals);
92 /* Query all available signals for this domain. */
93 if (req.nr_signals > 0) {
94 ret = etna_perfmon_query_signals(pm, dom);
98 } while (req.iter != 0xff);
103 static void etna_perfmon_free_signals(struct etna_perfmon_domain *dom)
105 struct etna_perfmon_signal *sig, *next;
107 LIST_FOR_EACH_ENTRY_SAFE(sig, next, &dom->signals, head) {
108 list_del(&sig->head);
113 static void etna_perfmon_free_domains(struct etna_perfmon *pm)
115 struct etna_perfmon_domain *dom, *next;
117 LIST_FOR_EACH_ENTRY_SAFE(dom, next, &pm->domains, head) {
118 etna_perfmon_free_signals(dom);
119 list_del(&dom->head);
124 drm_public struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe)
126 struct etna_perfmon *pm;
129 pm = calloc(1, sizeof(*pm));
131 ERROR_MSG("allocation failed");
135 list_inithead(&pm->domains);
138 /* query all available domains and sources for this device */
139 ret = etna_perfmon_query_domains(pm);
146 etna_perfmon_del(pm);
150 drm_public void etna_perfmon_del(struct etna_perfmon *pm)
155 etna_perfmon_free_domains(pm);
159 drm_public struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name)
161 struct etna_perfmon_domain *dom;
164 LIST_FOR_EACH_ENTRY(dom, &pm->domains, head) {
165 if (!strcmp(dom->name, name))
173 drm_public struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name)
175 struct etna_perfmon_signal *signal;
178 LIST_FOR_EACH_ENTRY(signal, &dom->signals, head) {
179 if (!strcmp(signal->name, name))