treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / etnaviv / etnaviv_perfmon.c
blob8adbf2861bff4fe805d8bac3c9ef7108e54e7bac
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2017 Etnaviv Project
4 * Copyright (C) 2017 Zodiac Inflight Innovations
5 */
7 #include "common.xml.h"
8 #include "etnaviv_gpu.h"
9 #include "etnaviv_perfmon.h"
10 #include "state_hi.xml.h"
12 struct etnaviv_pm_domain;
14 struct etnaviv_pm_signal {
15 char name[64];
16 u32 data;
18 u32 (*sample)(struct etnaviv_gpu *gpu,
19 const struct etnaviv_pm_domain *domain,
20 const struct etnaviv_pm_signal *signal);
23 struct etnaviv_pm_domain {
24 char name[64];
26 /* profile register */
27 u32 profile_read;
28 u32 profile_config;
30 u8 nr_signals;
31 const struct etnaviv_pm_signal *signal;
34 struct etnaviv_pm_domain_meta {
35 const struct etnaviv_pm_domain *domains;
36 u32 nr_domains;
39 static u32 perf_reg_read(struct etnaviv_gpu *gpu,
40 const struct etnaviv_pm_domain *domain,
41 const struct etnaviv_pm_signal *signal)
43 gpu_write(gpu, domain->profile_config, signal->data);
45 return gpu_read(gpu, domain->profile_read);
48 static u32 pipe_reg_read(struct etnaviv_gpu *gpu,
49 const struct etnaviv_pm_domain *domain,
50 const struct etnaviv_pm_signal *signal)
52 u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
53 u32 value = 0;
54 unsigned i;
56 for (i = 0; i < gpu->identity.pixel_pipes; i++) {
57 clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
58 clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(i);
59 gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
60 gpu_write(gpu, domain->profile_config, signal->data);
61 value += gpu_read(gpu, domain->profile_read);
64 /* switch back to pixel pipe 0 to prevent GPU hang */
65 clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
66 clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(0);
67 gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
69 return value;
72 static u32 hi_total_cycle_read(struct etnaviv_gpu *gpu,
73 const struct etnaviv_pm_domain *domain,
74 const struct etnaviv_pm_signal *signal)
76 u32 reg = VIVS_HI_PROFILE_TOTAL_CYCLES;
78 if (gpu->identity.model == chipModel_GC880 ||
79 gpu->identity.model == chipModel_GC2000 ||
80 gpu->identity.model == chipModel_GC2100)
81 reg = VIVS_MC_PROFILE_CYCLE_COUNTER;
83 return gpu_read(gpu, reg);
86 static u32 hi_total_idle_cycle_read(struct etnaviv_gpu *gpu,
87 const struct etnaviv_pm_domain *domain,
88 const struct etnaviv_pm_signal *signal)
90 u32 reg = VIVS_HI_PROFILE_IDLE_CYCLES;
92 if (gpu->identity.model == chipModel_GC880 ||
93 gpu->identity.model == chipModel_GC2000 ||
94 gpu->identity.model == chipModel_GC2100)
95 reg = VIVS_HI_PROFILE_TOTAL_CYCLES;
97 return gpu_read(gpu, reg);
100 static const struct etnaviv_pm_domain doms_3d[] = {
102 .name = "HI",
103 .profile_read = VIVS_MC_PROFILE_HI_READ,
104 .profile_config = VIVS_MC_PROFILE_CONFIG2,
105 .nr_signals = 5,
106 .signal = (const struct etnaviv_pm_signal[]) {
108 "TOTAL_CYCLES",
110 &hi_total_cycle_read
113 "IDLE_CYCLES",
115 &hi_total_idle_cycle_read
118 "AXI_CYCLES_READ_REQUEST_STALLED",
119 VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED,
120 &perf_reg_read
123 "AXI_CYCLES_WRITE_REQUEST_STALLED",
124 VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
125 &perf_reg_read
128 "AXI_CYCLES_WRITE_DATA_STALLED",
129 VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED,
130 &perf_reg_read
135 .name = "PE",
136 .profile_read = VIVS_MC_PROFILE_PE_READ,
137 .profile_config = VIVS_MC_PROFILE_CONFIG0,
138 .nr_signals = 4,
139 .signal = (const struct etnaviv_pm_signal[]) {
141 "PIXEL_COUNT_KILLED_BY_COLOR_PIPE",
142 VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
143 &pipe_reg_read
146 "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE",
147 VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
148 &pipe_reg_read
151 "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE",
152 VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
153 &pipe_reg_read
156 "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE",
157 VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
158 &pipe_reg_read
163 .name = "SH",
164 .profile_read = VIVS_MC_PROFILE_SH_READ,
165 .profile_config = VIVS_MC_PROFILE_CONFIG0,
166 .nr_signals = 9,
167 .signal = (const struct etnaviv_pm_signal[]) {
169 "SHADER_CYCLES",
170 VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES,
171 &perf_reg_read
174 "PS_INST_COUNTER",
175 VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER,
176 &perf_reg_read
179 "RENDERED_PIXEL_COUNTER",
180 VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER,
181 &perf_reg_read
184 "VS_INST_COUNTER",
185 VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER,
186 &pipe_reg_read
189 "RENDERED_VERTICE_COUNTER",
190 VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER,
191 &pipe_reg_read
194 "VTX_BRANCH_INST_COUNTER",
195 VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER,
196 &pipe_reg_read
199 "VTX_TEXLD_INST_COUNTER",
200 VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER,
201 &pipe_reg_read
204 "PXL_BRANCH_INST_COUNTER",
205 VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER,
206 &pipe_reg_read
209 "PXL_TEXLD_INST_COUNTER",
210 VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER,
211 &pipe_reg_read
216 .name = "PA",
217 .profile_read = VIVS_MC_PROFILE_PA_READ,
218 .profile_config = VIVS_MC_PROFILE_CONFIG1,
219 .nr_signals = 6,
220 .signal = (const struct etnaviv_pm_signal[]) {
222 "INPUT_VTX_COUNTER",
223 VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER,
224 &perf_reg_read
227 "INPUT_PRIM_COUNTER",
228 VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER,
229 &perf_reg_read
232 "OUTPUT_PRIM_COUNTER",
233 VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER,
234 &perf_reg_read
237 "DEPTH_CLIPPED_COUNTER",
238 VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER,
239 &pipe_reg_read
242 "TRIVIAL_REJECTED_COUNTER",
243 VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER,
244 &pipe_reg_read
247 "CULLED_COUNTER",
248 VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER,
249 &pipe_reg_read
254 .name = "SE",
255 .profile_read = VIVS_MC_PROFILE_SE_READ,
256 .profile_config = VIVS_MC_PROFILE_CONFIG1,
257 .nr_signals = 2,
258 .signal = (const struct etnaviv_pm_signal[]) {
260 "CULLED_TRIANGLE_COUNT",
261 VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT,
262 &perf_reg_read
265 "CULLED_LINES_COUNT",
266 VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT,
267 &perf_reg_read
272 .name = "RA",
273 .profile_read = VIVS_MC_PROFILE_RA_READ,
274 .profile_config = VIVS_MC_PROFILE_CONFIG1,
275 .nr_signals = 7,
276 .signal = (const struct etnaviv_pm_signal[]) {
278 "VALID_PIXEL_COUNT",
279 VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT,
280 &perf_reg_read
283 "TOTAL_QUAD_COUNT",
284 VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT,
285 &perf_reg_read
288 "VALID_QUAD_COUNT_AFTER_EARLY_Z",
289 VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
290 &perf_reg_read
293 "TOTAL_PRIMITIVE_COUNT",
294 VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT,
295 &perf_reg_read
298 "PIPE_CACHE_MISS_COUNTER",
299 VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER,
300 &perf_reg_read
303 "PREFETCH_CACHE_MISS_COUNTER",
304 VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER,
305 &perf_reg_read
308 "CULLED_QUAD_COUNT",
309 VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT,
310 &perf_reg_read
315 .name = "TX",
316 .profile_read = VIVS_MC_PROFILE_TX_READ,
317 .profile_config = VIVS_MC_PROFILE_CONFIG1,
318 .nr_signals = 9,
319 .signal = (const struct etnaviv_pm_signal[]) {
321 "TOTAL_BILINEAR_REQUESTS",
322 VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS,
323 &perf_reg_read
326 "TOTAL_TRILINEAR_REQUESTS",
327 VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS,
328 &perf_reg_read
331 "TOTAL_DISCARDED_TEXTURE_REQUESTS",
332 VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
333 &perf_reg_read
336 "TOTAL_TEXTURE_REQUESTS",
337 VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS,
338 &perf_reg_read
341 "MEM_READ_COUNT",
342 VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT,
343 &perf_reg_read
346 "MEM_READ_IN_8B_COUNT",
347 VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT,
348 &perf_reg_read
351 "CACHE_MISS_COUNT",
352 VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT,
353 &perf_reg_read
356 "CACHE_HIT_TEXEL_COUNT",
357 VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT,
358 &perf_reg_read
361 "CACHE_MISS_TEXEL_COUNT",
362 VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT,
363 &perf_reg_read
368 .name = "MC",
369 .profile_read = VIVS_MC_PROFILE_MC_READ,
370 .profile_config = VIVS_MC_PROFILE_CONFIG2,
371 .nr_signals = 3,
372 .signal = (const struct etnaviv_pm_signal[]) {
374 "TOTAL_READ_REQ_8B_FROM_PIPELINE",
375 VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
376 &perf_reg_read
379 "TOTAL_READ_REQ_8B_FROM_IP",
380 VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP,
381 &perf_reg_read
384 "TOTAL_WRITE_REQ_8B_FROM_PIPELINE",
385 VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
386 &perf_reg_read
392 static const struct etnaviv_pm_domain doms_2d[] = {
394 .name = "PE",
395 .profile_read = VIVS_MC_PROFILE_PE_READ,
396 .profile_config = VIVS_MC_PROFILE_CONFIG0,
397 .nr_signals = 1,
398 .signal = (const struct etnaviv_pm_signal[]) {
400 "PIXELS_RENDERED_2D",
401 VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D,
402 &pipe_reg_read
408 static const struct etnaviv_pm_domain doms_vg[] = {
411 static const struct etnaviv_pm_domain_meta doms_meta[] = {
413 .nr_domains = ARRAY_SIZE(doms_3d),
414 .domains = &doms_3d[0]
417 .nr_domains = ARRAY_SIZE(doms_2d),
418 .domains = &doms_2d[0]
421 .nr_domains = ARRAY_SIZE(doms_vg),
422 .domains = &doms_vg[0]
426 int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
427 struct drm_etnaviv_pm_domain *domain)
429 const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe];
430 const struct etnaviv_pm_domain *dom;
432 if (domain->iter >= meta->nr_domains)
433 return -EINVAL;
435 dom = meta->domains + domain->iter;
437 domain->id = domain->iter;
438 domain->nr_signals = dom->nr_signals;
439 strncpy(domain->name, dom->name, sizeof(domain->name));
441 domain->iter++;
442 if (domain->iter == meta->nr_domains)
443 domain->iter = 0xff;
445 return 0;
448 int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
449 struct drm_etnaviv_pm_signal *signal)
451 const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe];
452 const struct etnaviv_pm_domain *dom;
453 const struct etnaviv_pm_signal *sig;
455 if (signal->domain >= meta->nr_domains)
456 return -EINVAL;
458 dom = meta->domains + signal->domain;
460 if (signal->iter >= dom->nr_signals)
461 return -EINVAL;
463 sig = &dom->signal[signal->iter];
465 signal->id = signal->iter;
466 strncpy(signal->name, sig->name, sizeof(signal->name));
468 signal->iter++;
469 if (signal->iter == dom->nr_signals)
470 signal->iter = 0xffff;
472 return 0;
475 int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,
476 u32 exec_state)
478 const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
479 const struct etnaviv_pm_domain *dom;
481 if (r->domain >= meta->nr_domains)
482 return -EINVAL;
484 dom = meta->domains + r->domain;
486 if (r->signal >= dom->nr_signals)
487 return -EINVAL;
489 return 0;
492 void etnaviv_perfmon_process(struct etnaviv_gpu *gpu,
493 const struct etnaviv_perfmon_request *pmr, u32 exec_state)
495 const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
496 const struct etnaviv_pm_domain *dom;
497 const struct etnaviv_pm_signal *sig;
498 u32 *bo = pmr->bo_vma;
499 u32 val;
501 dom = meta->domains + pmr->domain;
502 sig = &dom->signal[pmr->signal];
503 val = sig->sample(gpu, dom, sig);
505 *(bo + pmr->offset) = val;