blob: f0cdf371663a8fb23d4b2e6ef2048a773d3414c7 [file] [log] [blame]
Christian Gmeiner9e2c2e22017-09-24 15:15:21 +02001/*
2 * Copyright (C) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "etnaviv_gpu.h"
Christian Gmeiner249300c2017-09-24 15:15:27 +020019#include "etnaviv_perfmon.h"
Christian Gmeiner33deff02017-09-24 15:15:31 +020020#include "state_hi.xml.h"
Christian Gmeiner9e2c2e22017-09-24 15:15:21 +020021
22struct etnaviv_pm_domain;
23
24struct etnaviv_pm_signal {
25 char name[64];
26 u32 data;
27
28 u32 (*sample)(struct etnaviv_gpu *gpu,
29 const struct etnaviv_pm_domain *domain,
30 const struct etnaviv_pm_signal *signal);
31};
32
33struct etnaviv_pm_domain {
34 char name[64];
Christian Gmeiner33deff02017-09-24 15:15:31 +020035
36 /* profile register */
37 u32 profile_read;
38 u32 profile_config;
39
Christian Gmeiner9e2c2e22017-09-24 15:15:21 +020040 u8 nr_signals;
41 const struct etnaviv_pm_signal *signal;
42};
43
44struct etnaviv_pm_domain_meta {
45 const struct etnaviv_pm_domain *domains;
46 u32 nr_domains;
47};
48
Christian Gmeiner33deff02017-09-24 15:15:31 +020049static u32 simple_reg_read(struct etnaviv_gpu *gpu,
50 const struct etnaviv_pm_domain *domain,
51 const struct etnaviv_pm_signal *signal)
52{
53 return gpu_read(gpu, signal->data);
54}
55
56static u32 perf_reg_read(struct etnaviv_gpu *gpu,
57 const struct etnaviv_pm_domain *domain,
58 const struct etnaviv_pm_signal *signal)
59{
60 gpu_write(gpu, domain->profile_config, signal->data);
61
62 return gpu_read(gpu, domain->profile_read);
63}
64
Christian Gmeiner9e2c2e22017-09-24 15:15:21 +020065static const struct etnaviv_pm_domain doms_3d[] = {
Christian Gmeiner33deff02017-09-24 15:15:31 +020066 {
67 .name = "HI",
68 .profile_read = VIVS_MC_PROFILE_HI_READ,
69 .profile_config = VIVS_MC_PROFILE_CONFIG2,
70 .nr_signals = 5,
71 .signal = (const struct etnaviv_pm_signal[]) {
72 {
73 "TOTAL_CYCLES",
74 VIVS_HI_PROFILE_TOTAL_CYCLES,
75 &simple_reg_read
76 },
77 {
78 "IDLE_CYCLES",
79 VIVS_HI_PROFILE_IDLE_CYCLES,
80 &simple_reg_read
81 },
82 {
83 "AXI_CYCLES_READ_REQUEST_STALLED",
84 VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED,
85 &perf_reg_read
86 },
87 {
88 "AXI_CYCLES_WRITE_REQUEST_STALLED",
89 VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
90 &perf_reg_read
91 },
92 {
93 "AXI_CYCLES_WRITE_DATA_STALLED",
94 VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED,
95 &perf_reg_read
96 }
97 }
98 }
Christian Gmeiner9e2c2e22017-09-24 15:15:21 +020099};
100
101static const struct etnaviv_pm_domain doms_2d[] = {
102};
103
104static const struct etnaviv_pm_domain doms_vg[] = {
105};
106
107static const struct etnaviv_pm_domain_meta doms_meta[] = {
108 {
109 .nr_domains = ARRAY_SIZE(doms_3d),
110 .domains = &doms_3d[0]
111 },
112 {
113 .nr_domains = ARRAY_SIZE(doms_2d),
114 .domains = &doms_2d[0]
115 },
116 {
117 .nr_domains = ARRAY_SIZE(doms_vg),
118 .domains = &doms_vg[0]
119 }
120};
121
122int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
123 struct drm_etnaviv_pm_domain *domain)
124{
125 const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe];
126 const struct etnaviv_pm_domain *dom;
127
128 if (domain->iter >= meta->nr_domains)
129 return -EINVAL;
130
131 dom = meta->domains + domain->iter;
132
133 domain->id = domain->iter;
134 domain->nr_signals = dom->nr_signals;
135 strncpy(domain->name, dom->name, sizeof(domain->name));
136
137 domain->iter++;
138 if (domain->iter == meta->nr_domains)
139 domain->iter = 0xff;
140
141 return 0;
142}
143
144int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
145 struct drm_etnaviv_pm_signal *signal)
146{
147 const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe];
148 const struct etnaviv_pm_domain *dom;
149 const struct etnaviv_pm_signal *sig;
150
151 if (signal->domain >= meta->nr_domains)
152 return -EINVAL;
153
154 dom = meta->domains + signal->domain;
155
156 if (signal->iter > dom->nr_signals)
157 return -EINVAL;
158
159 sig = &dom->signal[signal->iter];
160
161 signal->id = signal->iter;
162 strncpy(signal->name, sig->name, sizeof(signal->name));
163
164 signal->iter++;
165 if (signal->iter == dom->nr_signals)
166 signal->iter = 0xffff;
167
168 return 0;
169}
Christian Gmeiner46df52c2017-09-24 15:15:25 +0200170
171int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,
172 u32 exec_state)
173{
174 const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
175 const struct etnaviv_pm_domain *dom;
176
177 if (r->domain >= meta->nr_domains)
178 return -EINVAL;
179
180 dom = meta->domains + r->domain;
181
182 if (r->signal > dom->nr_signals)
183 return -EINVAL;
184
185 return 0;
186}
Christian Gmeiner249300c2017-09-24 15:15:27 +0200187
188void etnaviv_perfmon_process(struct etnaviv_gpu *gpu,
189 const struct etnaviv_perfmon_request *pmr)
190{
191 const struct etnaviv_pm_domain_meta *meta = &doms_meta[gpu->exec_state];
192 const struct etnaviv_pm_domain *dom;
193 const struct etnaviv_pm_signal *sig;
194 u32 *bo = pmr->bo_vma;
195 u32 val;
196
197 dom = meta->domains + pmr->domain;
198 sig = &dom->signal[pmr->signal];
199 val = sig->sample(gpu, dom, sig);
200
201 *(bo + pmr->offset) = val;
202}