1d722e3fbSopenharmony_ci/* 2d722e3fbSopenharmony_ci * Copyright (C) 2017 Etnaviv Project 3d722e3fbSopenharmony_ci * Copyright (C) 2017 Zodiac Inflight Innovations 4d722e3fbSopenharmony_ci * 5d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 8d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11d722e3fbSopenharmony_ci * 12d722e3fbSopenharmony_ci * The above copyright notice and this permission notice (including the next 13d722e3fbSopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14d722e3fbSopenharmony_ci * Software. 15d722e3fbSopenharmony_ci * 16d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19d722e3fbSopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d722e3fbSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21d722e3fbSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22d722e3fbSopenharmony_ci * SOFTWARE. 23d722e3fbSopenharmony_ci * 24d722e3fbSopenharmony_ci * Authors: 25d722e3fbSopenharmony_ci * Christian Gmeiner <christian.gmeiner@gmail.com> 26d722e3fbSopenharmony_ci */ 27d722e3fbSopenharmony_ci 28d722e3fbSopenharmony_ci#include "etnaviv_priv.h" 29d722e3fbSopenharmony_ci 30d722e3fbSopenharmony_cistatic int etna_perfmon_query_signals(struct etna_perfmon *pm, struct etna_perfmon_domain *dom) 31d722e3fbSopenharmony_ci{ 32d722e3fbSopenharmony_ci struct etna_device *dev = pm->pipe->gpu->dev; 33d722e3fbSopenharmony_ci struct drm_etnaviv_pm_signal req = { 34d722e3fbSopenharmony_ci .pipe = pm->pipe->id, 35d722e3fbSopenharmony_ci .domain = dom->id 36d722e3fbSopenharmony_ci }; 37d722e3fbSopenharmony_ci 38d722e3fbSopenharmony_ci do { 39d722e3fbSopenharmony_ci struct etna_perfmon_signal *sig; 40d722e3fbSopenharmony_ci int ret; 41d722e3fbSopenharmony_ci 42d722e3fbSopenharmony_ci ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_SIG, &req, sizeof(req)); 43d722e3fbSopenharmony_ci if (ret) 44d722e3fbSopenharmony_ci break; 45d722e3fbSopenharmony_ci 46d722e3fbSopenharmony_ci sig = calloc(1, sizeof(*sig)); 47d722e3fbSopenharmony_ci if (!sig) 48d722e3fbSopenharmony_ci return -ENOMEM; 49d722e3fbSopenharmony_ci 50d722e3fbSopenharmony_ci INFO_MSG("perfmon signal:"); 51d722e3fbSopenharmony_ci INFO_MSG("id = %d", req.id); 52d722e3fbSopenharmony_ci INFO_MSG("name = %s", req.name); 53d722e3fbSopenharmony_ci 54d722e3fbSopenharmony_ci sig->domain = dom; 55d722e3fbSopenharmony_ci sig->signal = req.id; 56d722e3fbSopenharmony_ci strncpy(sig->name, req.name, sizeof(sig->name)); 57d722e3fbSopenharmony_ci list_addtail(&sig->head, &dom->signals); 58d722e3fbSopenharmony_ci } while (req.iter != 0xffff); 59d722e3fbSopenharmony_ci 60d722e3fbSopenharmony_ci return 0; 61d722e3fbSopenharmony_ci} 62d722e3fbSopenharmony_ci 63d722e3fbSopenharmony_cistatic int etna_perfmon_query_domains(struct etna_perfmon *pm) 64d722e3fbSopenharmony_ci{ 65d722e3fbSopenharmony_ci struct etna_device *dev = pm->pipe->gpu->dev; 66d722e3fbSopenharmony_ci struct drm_etnaviv_pm_domain req = { 67d722e3fbSopenharmony_ci .pipe = pm->pipe->id 68d722e3fbSopenharmony_ci }; 69d722e3fbSopenharmony_ci 70d722e3fbSopenharmony_ci do { 71d722e3fbSopenharmony_ci struct etna_perfmon_domain *dom; 72d722e3fbSopenharmony_ci int ret; 73d722e3fbSopenharmony_ci 74d722e3fbSopenharmony_ci ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_DOM, &req, sizeof(req)); 75d722e3fbSopenharmony_ci if (ret) 76d722e3fbSopenharmony_ci break; 77d722e3fbSopenharmony_ci 78d722e3fbSopenharmony_ci dom = calloc(1, sizeof(*dom)); 79d722e3fbSopenharmony_ci if (!dom) 80d722e3fbSopenharmony_ci return -ENOMEM; 81d722e3fbSopenharmony_ci 82d722e3fbSopenharmony_ci list_inithead(&dom->signals); 83d722e3fbSopenharmony_ci dom->id = req.id; 84d722e3fbSopenharmony_ci strncpy(dom->name, req.name, sizeof(dom->name)); 85d722e3fbSopenharmony_ci list_addtail(&dom->head, &pm->domains); 86d722e3fbSopenharmony_ci 87d722e3fbSopenharmony_ci INFO_MSG("perfmon domain:"); 88d722e3fbSopenharmony_ci INFO_MSG("id = %d", req.id); 89d722e3fbSopenharmony_ci INFO_MSG("name = %s", req.name); 90d722e3fbSopenharmony_ci INFO_MSG("nr_signals = %d", req.nr_signals); 91d722e3fbSopenharmony_ci 92d722e3fbSopenharmony_ci /* Query all available signals for this domain. */ 93d722e3fbSopenharmony_ci if (req.nr_signals > 0) { 94d722e3fbSopenharmony_ci ret = etna_perfmon_query_signals(pm, dom); 95d722e3fbSopenharmony_ci if (ret) 96d722e3fbSopenharmony_ci return ret; 97d722e3fbSopenharmony_ci } 98d722e3fbSopenharmony_ci } while (req.iter != 0xff); 99d722e3fbSopenharmony_ci 100d722e3fbSopenharmony_ci return 0; 101d722e3fbSopenharmony_ci} 102d722e3fbSopenharmony_ci 103d722e3fbSopenharmony_cistatic void etna_perfmon_free_signals(struct etna_perfmon_domain *dom) 104d722e3fbSopenharmony_ci{ 105d722e3fbSopenharmony_ci struct etna_perfmon_signal *sig, *next; 106d722e3fbSopenharmony_ci 107d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY_SAFE(sig, next, &dom->signals, head) { 108d722e3fbSopenharmony_ci list_del(&sig->head); 109d722e3fbSopenharmony_ci free(sig); 110d722e3fbSopenharmony_ci } 111d722e3fbSopenharmony_ci} 112d722e3fbSopenharmony_ci 113d722e3fbSopenharmony_cistatic void etna_perfmon_free_domains(struct etna_perfmon *pm) 114d722e3fbSopenharmony_ci{ 115d722e3fbSopenharmony_ci struct etna_perfmon_domain *dom, *next; 116d722e3fbSopenharmony_ci 117d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY_SAFE(dom, next, &pm->domains, head) { 118d722e3fbSopenharmony_ci etna_perfmon_free_signals(dom); 119d722e3fbSopenharmony_ci list_del(&dom->head); 120d722e3fbSopenharmony_ci free(dom); 121d722e3fbSopenharmony_ci } 122d722e3fbSopenharmony_ci} 123d722e3fbSopenharmony_ci 124d722e3fbSopenharmony_cidrm_public struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe) 125d722e3fbSopenharmony_ci{ 126d722e3fbSopenharmony_ci struct etna_perfmon *pm; 127d722e3fbSopenharmony_ci int ret; 128d722e3fbSopenharmony_ci 129d722e3fbSopenharmony_ci pm = calloc(1, sizeof(*pm)); 130d722e3fbSopenharmony_ci if (!pm) { 131d722e3fbSopenharmony_ci ERROR_MSG("allocation failed"); 132d722e3fbSopenharmony_ci return NULL; 133d722e3fbSopenharmony_ci } 134d722e3fbSopenharmony_ci 135d722e3fbSopenharmony_ci list_inithead(&pm->domains); 136d722e3fbSopenharmony_ci pm->pipe = pipe; 137d722e3fbSopenharmony_ci 138d722e3fbSopenharmony_ci /* query all available domains and sources for this device */ 139d722e3fbSopenharmony_ci ret = etna_perfmon_query_domains(pm); 140d722e3fbSopenharmony_ci if (ret) 141d722e3fbSopenharmony_ci goto fail; 142d722e3fbSopenharmony_ci 143d722e3fbSopenharmony_ci return pm; 144d722e3fbSopenharmony_ci 145d722e3fbSopenharmony_cifail: 146d722e3fbSopenharmony_ci etna_perfmon_del(pm); 147d722e3fbSopenharmony_ci return NULL; 148d722e3fbSopenharmony_ci} 149d722e3fbSopenharmony_ci 150d722e3fbSopenharmony_cidrm_public void etna_perfmon_del(struct etna_perfmon *pm) 151d722e3fbSopenharmony_ci{ 152d722e3fbSopenharmony_ci if (!pm) 153d722e3fbSopenharmony_ci return; 154d722e3fbSopenharmony_ci 155d722e3fbSopenharmony_ci etna_perfmon_free_domains(pm); 156d722e3fbSopenharmony_ci free(pm); 157d722e3fbSopenharmony_ci} 158d722e3fbSopenharmony_ci 159d722e3fbSopenharmony_cidrm_public struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name) 160d722e3fbSopenharmony_ci{ 161d722e3fbSopenharmony_ci struct etna_perfmon_domain *dom; 162d722e3fbSopenharmony_ci 163d722e3fbSopenharmony_ci if (pm) { 164d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY(dom, &pm->domains, head) { 165d722e3fbSopenharmony_ci if (!strcmp(dom->name, name)) 166d722e3fbSopenharmony_ci return dom; 167d722e3fbSopenharmony_ci } 168d722e3fbSopenharmony_ci } 169d722e3fbSopenharmony_ci 170d722e3fbSopenharmony_ci return NULL; 171d722e3fbSopenharmony_ci} 172d722e3fbSopenharmony_ci 173d722e3fbSopenharmony_cidrm_public struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name) 174d722e3fbSopenharmony_ci{ 175d722e3fbSopenharmony_ci struct etna_perfmon_signal *signal; 176d722e3fbSopenharmony_ci 177d722e3fbSopenharmony_ci if (dom) { 178d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY(signal, &dom->signals, head) { 179d722e3fbSopenharmony_ci if (!strcmp(signal->name, name)) 180d722e3fbSopenharmony_ci return signal; 181d722e3fbSopenharmony_ci } 182d722e3fbSopenharmony_ci } 183d722e3fbSopenharmony_ci 184d722e3fbSopenharmony_ci return NULL; 185d722e3fbSopenharmony_ci} 186