]>
Commit | Line | Data |
---|---|---|
9e2c2e27 CG |
1 | /* |
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" | |
249300c7 | 19 | #include "etnaviv_perfmon.h" |
33deff0a | 20 | #include "state_hi.xml.h" |
9e2c2e27 CG |
21 | |
22 | struct etnaviv_pm_domain; | |
23 | ||
24 | struct 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 | ||
33 | struct etnaviv_pm_domain { | |
34 | char name[64]; | |
33deff0a CG |
35 | |
36 | /* profile register */ | |
37 | u32 profile_read; | |
38 | u32 profile_config; | |
39 | ||
9e2c2e27 CG |
40 | u8 nr_signals; |
41 | const struct etnaviv_pm_signal *signal; | |
42 | }; | |
43 | ||
44 | struct etnaviv_pm_domain_meta { | |
45 | const struct etnaviv_pm_domain *domains; | |
46 | u32 nr_domains; | |
47 | }; | |
48 | ||
33deff0a CG |
49 | static 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 | ||
56 | static 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 | ||
a3d0c390 CG |
65 | static u32 pipe_reg_read(struct etnaviv_gpu *gpu, |
66 | const struct etnaviv_pm_domain *domain, | |
67 | const struct etnaviv_pm_signal *signal) | |
68 | { | |
69 | u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); | |
70 | u32 value = 0; | |
71 | unsigned i; | |
72 | ||
73 | for (i = 0; i < gpu->identity.pixel_pipes; i++) { | |
74 | clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK); | |
75 | clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(i); | |
76 | gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock); | |
77 | gpu_write(gpu, domain->profile_config, signal->data); | |
78 | value += gpu_read(gpu, domain->profile_read); | |
79 | } | |
80 | ||
81 | /* switch back to pixel pipe 0 to prevent GPU hang */ | |
82 | clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK); | |
83 | clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(0); | |
84 | gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock); | |
85 | ||
86 | return value; | |
87 | } | |
88 | ||
9e2c2e27 | 89 | static const struct etnaviv_pm_domain doms_3d[] = { |
33deff0a CG |
90 | { |
91 | .name = "HI", | |
92 | .profile_read = VIVS_MC_PROFILE_HI_READ, | |
93 | .profile_config = VIVS_MC_PROFILE_CONFIG2, | |
94 | .nr_signals = 5, | |
95 | .signal = (const struct etnaviv_pm_signal[]) { | |
96 | { | |
97 | "TOTAL_CYCLES", | |
98 | VIVS_HI_PROFILE_TOTAL_CYCLES, | |
99 | &simple_reg_read | |
100 | }, | |
101 | { | |
102 | "IDLE_CYCLES", | |
103 | VIVS_HI_PROFILE_IDLE_CYCLES, | |
104 | &simple_reg_read | |
105 | }, | |
106 | { | |
107 | "AXI_CYCLES_READ_REQUEST_STALLED", | |
108 | VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED, | |
109 | &perf_reg_read | |
110 | }, | |
111 | { | |
112 | "AXI_CYCLES_WRITE_REQUEST_STALLED", | |
113 | VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED, | |
114 | &perf_reg_read | |
115 | }, | |
116 | { | |
117 | "AXI_CYCLES_WRITE_DATA_STALLED", | |
118 | VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED, | |
119 | &perf_reg_read | |
120 | } | |
121 | } | |
a3d0c390 CG |
122 | }, |
123 | { | |
124 | .name = "PE", | |
125 | .profile_read = VIVS_MC_PROFILE_PE_READ, | |
126 | .profile_config = VIVS_MC_PROFILE_CONFIG0, | |
94245618 | 127 | .nr_signals = 4, |
a3d0c390 CG |
128 | .signal = (const struct etnaviv_pm_signal[]) { |
129 | { | |
130 | "PIXEL_COUNT_KILLED_BY_COLOR_PIPE", | |
131 | VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE, | |
132 | &pipe_reg_read | |
133 | }, | |
134 | { | |
135 | "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE", | |
136 | VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE, | |
137 | &pipe_reg_read | |
138 | }, | |
139 | { | |
140 | "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE", | |
141 | VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE, | |
142 | &pipe_reg_read | |
143 | }, | |
144 | { | |
145 | "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE", | |
146 | VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE, | |
147 | &pipe_reg_read | |
148 | } | |
149 | } | |
98b2482e CG |
150 | }, |
151 | { | |
152 | .name = "SH", | |
153 | .profile_read = VIVS_MC_PROFILE_SH_READ, | |
154 | .profile_config = VIVS_MC_PROFILE_CONFIG0, | |
155 | .nr_signals = 9, | |
156 | .signal = (const struct etnaviv_pm_signal[]) { | |
157 | { | |
158 | "SHADER_CYCLES", | |
159 | VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES, | |
160 | &perf_reg_read | |
161 | }, | |
162 | { | |
163 | "PS_INST_COUNTER", | |
164 | VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER, | |
165 | &perf_reg_read | |
166 | }, | |
167 | { | |
168 | "RENDERED_PIXEL_COUNTER", | |
169 | VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER, | |
170 | &perf_reg_read | |
171 | }, | |
172 | { | |
173 | "VS_INST_COUNTER", | |
174 | VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER, | |
175 | &pipe_reg_read | |
176 | }, | |
177 | { | |
178 | "RENDERED_VERTICE_COUNTER", | |
179 | VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER, | |
180 | &pipe_reg_read | |
181 | }, | |
182 | { | |
183 | "VTX_BRANCH_INST_COUNTER", | |
184 | VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER, | |
185 | &pipe_reg_read | |
186 | }, | |
187 | { | |
188 | "VTX_TEXLD_INST_COUNTER", | |
189 | VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER, | |
190 | &pipe_reg_read | |
191 | }, | |
192 | { | |
193 | "PXL_BRANCH_INST_COUNTER", | |
194 | VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER, | |
195 | &pipe_reg_read | |
196 | }, | |
197 | { | |
198 | "PXL_TEXLD_INST_COUNTER", | |
199 | VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER, | |
200 | &pipe_reg_read | |
201 | } | |
202 | } | |
c3787ff6 CG |
203 | }, |
204 | { | |
205 | .name = "PA", | |
206 | .profile_read = VIVS_MC_PROFILE_PA_READ, | |
207 | .profile_config = VIVS_MC_PROFILE_CONFIG1, | |
208 | .nr_signals = 6, | |
209 | .signal = (const struct etnaviv_pm_signal[]) { | |
210 | { | |
211 | "INPUT_VTX_COUNTER", | |
212 | VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER, | |
213 | &perf_reg_read | |
214 | }, | |
215 | { | |
216 | "INPUT_PRIM_COUNTER", | |
217 | VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER, | |
218 | &perf_reg_read | |
219 | }, | |
220 | { | |
221 | "OUTPUT_PRIM_COUNTER", | |
222 | VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER, | |
223 | &perf_reg_read | |
224 | }, | |
225 | { | |
226 | "DEPTH_CLIPPED_COUNTER", | |
227 | VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER, | |
228 | &pipe_reg_read | |
229 | }, | |
230 | { | |
231 | "TRIVIAL_REJECTED_COUNTER", | |
232 | VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER, | |
233 | &pipe_reg_read | |
234 | }, | |
235 | { | |
236 | "CULLED_COUNTER", | |
237 | VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER, | |
238 | &pipe_reg_read | |
239 | } | |
240 | } | |
a515264c CG |
241 | }, |
242 | { | |
243 | .name = "SE", | |
244 | .profile_read = VIVS_MC_PROFILE_SE_READ, | |
245 | .profile_config = VIVS_MC_PROFILE_CONFIG1, | |
246 | .nr_signals = 2, | |
247 | .signal = (const struct etnaviv_pm_signal[]) { | |
248 | { | |
249 | "CULLED_TRIANGLE_COUNT", | |
250 | VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT, | |
251 | &perf_reg_read | |
252 | }, | |
253 | { | |
254 | "CULLED_LINES_COUNT", | |
255 | VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT, | |
256 | &perf_reg_read | |
257 | } | |
258 | } | |
91a9a17b CG |
259 | }, |
260 | { | |
261 | .name = "RA", | |
262 | .profile_read = VIVS_MC_PROFILE_RA_READ, | |
263 | .profile_config = VIVS_MC_PROFILE_CONFIG1, | |
264 | .nr_signals = 7, | |
265 | .signal = (const struct etnaviv_pm_signal[]) { | |
266 | { | |
267 | "VALID_PIXEL_COUNT", | |
268 | VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT, | |
269 | &perf_reg_read | |
270 | }, | |
271 | { | |
272 | "TOTAL_QUAD_COUNT", | |
273 | VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT, | |
274 | &perf_reg_read | |
275 | }, | |
276 | { | |
277 | "VALID_QUAD_COUNT_AFTER_EARLY_Z", | |
278 | VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z, | |
279 | &perf_reg_read | |
280 | }, | |
281 | { | |
282 | "TOTAL_PRIMITIVE_COUNT", | |
283 | VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT, | |
284 | &perf_reg_read | |
285 | }, | |
286 | { | |
287 | "PIPE_CACHE_MISS_COUNTER", | |
288 | VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER, | |
289 | &perf_reg_read | |
290 | }, | |
291 | { | |
292 | "PREFETCH_CACHE_MISS_COUNTER", | |
293 | VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER, | |
294 | &perf_reg_read | |
295 | }, | |
296 | { | |
297 | "CULLED_QUAD_COUNT", | |
298 | VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT, | |
299 | &perf_reg_read | |
300 | } | |
301 | } | |
9646025e CG |
302 | }, |
303 | { | |
304 | .name = "TX", | |
305 | .profile_read = VIVS_MC_PROFILE_TX_READ, | |
306 | .profile_config = VIVS_MC_PROFILE_CONFIG1, | |
307 | .nr_signals = 9, | |
308 | .signal = (const struct etnaviv_pm_signal[]) { | |
309 | { | |
310 | "TOTAL_BILINEAR_REQUESTS", | |
311 | VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS, | |
312 | &perf_reg_read | |
313 | }, | |
314 | { | |
315 | "TOTAL_TRILINEAR_REQUESTS", | |
316 | VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS, | |
317 | &perf_reg_read | |
318 | }, | |
319 | { | |
320 | "TOTAL_DISCARDED_TEXTURE_REQUESTS", | |
321 | VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS, | |
322 | &perf_reg_read | |
323 | }, | |
324 | { | |
325 | "TOTAL_TEXTURE_REQUESTS", | |
326 | VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS, | |
327 | &perf_reg_read | |
328 | }, | |
329 | { | |
330 | "MEM_READ_COUNT", | |
331 | VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT, | |
332 | &perf_reg_read | |
333 | }, | |
334 | { | |
335 | "MEM_READ_IN_8B_COUNT", | |
336 | VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT, | |
337 | &perf_reg_read | |
338 | }, | |
339 | { | |
340 | "CACHE_MISS_COUNT", | |
341 | VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT, | |
342 | &perf_reg_read | |
343 | }, | |
344 | { | |
345 | "CACHE_HIT_TEXEL_COUNT", | |
346 | VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT, | |
347 | &perf_reg_read | |
348 | }, | |
349 | { | |
350 | "CACHE_MISS_TEXEL_COUNT", | |
351 | VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT, | |
352 | &perf_reg_read | |
353 | } | |
354 | } | |
49168ee9 CG |
355 | }, |
356 | { | |
357 | .name = "MC", | |
358 | .profile_read = VIVS_MC_PROFILE_MC_READ, | |
359 | .profile_config = VIVS_MC_PROFILE_CONFIG2, | |
360 | .nr_signals = 3, | |
361 | .signal = (const struct etnaviv_pm_signal[]) { | |
362 | { | |
363 | "TOTAL_READ_REQ_8B_FROM_PIPELINE", | |
364 | VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE, | |
365 | &perf_reg_read | |
366 | }, | |
367 | { | |
368 | "TOTAL_READ_REQ_8B_FROM_IP", | |
369 | VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP, | |
370 | &perf_reg_read | |
371 | }, | |
372 | { | |
373 | "TOTAL_WRITE_REQ_8B_FROM_PIPELINE", | |
374 | VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE, | |
375 | &perf_reg_read | |
376 | } | |
377 | } | |
33deff0a | 378 | } |
9e2c2e27 CG |
379 | }; |
380 | ||
381 | static const struct etnaviv_pm_domain doms_2d[] = { | |
a3d0c390 CG |
382 | { |
383 | .name = "PE", | |
384 | .profile_read = VIVS_MC_PROFILE_PE_READ, | |
385 | .profile_config = VIVS_MC_PROFILE_CONFIG0, | |
386 | .nr_signals = 1, | |
387 | .signal = (const struct etnaviv_pm_signal[]) { | |
388 | { | |
389 | "PIXELS_RENDERED_2D", | |
390 | VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D, | |
391 | &pipe_reg_read | |
392 | } | |
393 | } | |
394 | } | |
9e2c2e27 CG |
395 | }; |
396 | ||
397 | static const struct etnaviv_pm_domain doms_vg[] = { | |
398 | }; | |
399 | ||
400 | static const struct etnaviv_pm_domain_meta doms_meta[] = { | |
401 | { | |
402 | .nr_domains = ARRAY_SIZE(doms_3d), | |
403 | .domains = &doms_3d[0] | |
404 | }, | |
405 | { | |
406 | .nr_domains = ARRAY_SIZE(doms_2d), | |
407 | .domains = &doms_2d[0] | |
408 | }, | |
409 | { | |
410 | .nr_domains = ARRAY_SIZE(doms_vg), | |
411 | .domains = &doms_vg[0] | |
412 | } | |
413 | }; | |
414 | ||
415 | int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, | |
416 | struct drm_etnaviv_pm_domain *domain) | |
417 | { | |
418 | const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe]; | |
419 | const struct etnaviv_pm_domain *dom; | |
420 | ||
421 | if (domain->iter >= meta->nr_domains) | |
422 | return -EINVAL; | |
423 | ||
424 | dom = meta->domains + domain->iter; | |
425 | ||
426 | domain->id = domain->iter; | |
427 | domain->nr_signals = dom->nr_signals; | |
428 | strncpy(domain->name, dom->name, sizeof(domain->name)); | |
429 | ||
430 | domain->iter++; | |
431 | if (domain->iter == meta->nr_domains) | |
432 | domain->iter = 0xff; | |
433 | ||
434 | return 0; | |
435 | } | |
436 | ||
437 | int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, | |
438 | struct drm_etnaviv_pm_signal *signal) | |
439 | { | |
440 | const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe]; | |
441 | const struct etnaviv_pm_domain *dom; | |
442 | const struct etnaviv_pm_signal *sig; | |
443 | ||
444 | if (signal->domain >= meta->nr_domains) | |
445 | return -EINVAL; | |
446 | ||
447 | dom = meta->domains + signal->domain; | |
448 | ||
94245618 | 449 | if (signal->iter >= dom->nr_signals) |
9e2c2e27 CG |
450 | return -EINVAL; |
451 | ||
452 | sig = &dom->signal[signal->iter]; | |
453 | ||
454 | signal->id = signal->iter; | |
455 | strncpy(signal->name, sig->name, sizeof(signal->name)); | |
456 | ||
457 | signal->iter++; | |
458 | if (signal->iter == dom->nr_signals) | |
459 | signal->iter = 0xffff; | |
460 | ||
461 | return 0; | |
462 | } | |
46df52cd CG |
463 | |
464 | int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r, | |
465 | u32 exec_state) | |
466 | { | |
467 | const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state]; | |
468 | const struct etnaviv_pm_domain *dom; | |
469 | ||
470 | if (r->domain >= meta->nr_domains) | |
471 | return -EINVAL; | |
472 | ||
473 | dom = meta->domains + r->domain; | |
474 | ||
94245618 | 475 | if (r->signal >= dom->nr_signals) |
46df52cd CG |
476 | return -EINVAL; |
477 | ||
478 | return 0; | |
479 | } | |
249300c7 CG |
480 | |
481 | void etnaviv_perfmon_process(struct etnaviv_gpu *gpu, | |
482 | const struct etnaviv_perfmon_request *pmr) | |
483 | { | |
484 | const struct etnaviv_pm_domain_meta *meta = &doms_meta[gpu->exec_state]; | |
485 | const struct etnaviv_pm_domain *dom; | |
486 | const struct etnaviv_pm_signal *sig; | |
487 | u32 *bo = pmr->bo_vma; | |
488 | u32 val; | |
489 | ||
490 | dom = meta->domains + pmr->domain; | |
491 | sig = &dom->signal[pmr->signal]; | |
492 | val = sig->sample(gpu, dom, sig); | |
493 | ||
494 | *(bo + pmr->offset) = val; | |
495 | } |