1f6ffbd4fSLucas Stach // SPDX-License-Identifier: GPL-2.0
29e2c2e27SChristian Gmeiner /*
39e2c2e27SChristian Gmeiner * Copyright (C) 2017 Etnaviv Project
49e2c2e27SChristian Gmeiner * Copyright (C) 2017 Zodiac Inflight Innovations
59e2c2e27SChristian Gmeiner */
69e2c2e27SChristian Gmeiner
715ff4a7bSChristian Gmeiner #include "common.xml.h"
89e2c2e27SChristian Gmeiner #include "etnaviv_gpu.h"
9249300c7SChristian Gmeiner #include "etnaviv_perfmon.h"
1033deff0aSChristian Gmeiner #include "state_hi.xml.h"
119e2c2e27SChristian Gmeiner
129e2c2e27SChristian Gmeiner struct etnaviv_pm_domain;
139e2c2e27SChristian Gmeiner
149e2c2e27SChristian Gmeiner struct etnaviv_pm_signal {
159e2c2e27SChristian Gmeiner char name[64];
169e2c2e27SChristian Gmeiner u32 data;
179e2c2e27SChristian Gmeiner
189e2c2e27SChristian Gmeiner u32 (*sample)(struct etnaviv_gpu *gpu,
199e2c2e27SChristian Gmeiner const struct etnaviv_pm_domain *domain,
209e2c2e27SChristian Gmeiner const struct etnaviv_pm_signal *signal);
219e2c2e27SChristian Gmeiner };
229e2c2e27SChristian Gmeiner
239e2c2e27SChristian Gmeiner struct etnaviv_pm_domain {
249e2c2e27SChristian Gmeiner char name[64];
2533deff0aSChristian Gmeiner
2633deff0aSChristian Gmeiner /* profile register */
2733deff0aSChristian Gmeiner u32 profile_read;
2833deff0aSChristian Gmeiner u32 profile_config;
2933deff0aSChristian Gmeiner
309e2c2e27SChristian Gmeiner u8 nr_signals;
319e2c2e27SChristian Gmeiner const struct etnaviv_pm_signal *signal;
329e2c2e27SChristian Gmeiner };
339e2c2e27SChristian Gmeiner
349e2c2e27SChristian Gmeiner struct etnaviv_pm_domain_meta {
35ed1dd899SChristian Gmeiner unsigned int feature;
369e2c2e27SChristian Gmeiner const struct etnaviv_pm_domain *domains;
379e2c2e27SChristian Gmeiner u32 nr_domains;
389e2c2e27SChristian Gmeiner };
399e2c2e27SChristian Gmeiner
perf_reg_read(struct etnaviv_gpu * gpu,const struct etnaviv_pm_domain * domain,const struct etnaviv_pm_signal * signal)4033deff0aSChristian Gmeiner static u32 perf_reg_read(struct etnaviv_gpu *gpu,
4133deff0aSChristian Gmeiner const struct etnaviv_pm_domain *domain,
4233deff0aSChristian Gmeiner const struct etnaviv_pm_signal *signal)
4333deff0aSChristian Gmeiner {
4433deff0aSChristian Gmeiner gpu_write(gpu, domain->profile_config, signal->data);
4533deff0aSChristian Gmeiner
4633deff0aSChristian Gmeiner return gpu_read(gpu, domain->profile_read);
4733deff0aSChristian Gmeiner }
4833deff0aSChristian Gmeiner
pipe_select(struct etnaviv_gpu * gpu,u32 clock,unsigned pipe)49*a5cafb90SChristian Gmeiner static inline void pipe_select(struct etnaviv_gpu *gpu, u32 clock, unsigned pipe)
50*a5cafb90SChristian Gmeiner {
51*a5cafb90SChristian Gmeiner clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
52*a5cafb90SChristian Gmeiner clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(pipe);
53*a5cafb90SChristian Gmeiner
54*a5cafb90SChristian Gmeiner gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
55*a5cafb90SChristian Gmeiner }
56*a5cafb90SChristian Gmeiner
pipe_perf_reg_read(struct etnaviv_gpu * gpu,const struct etnaviv_pm_domain * domain,const struct etnaviv_pm_signal * signal)5777dfb36aSChristian Gmeiner static u32 pipe_perf_reg_read(struct etnaviv_gpu *gpu,
58a3d0c390SChristian Gmeiner const struct etnaviv_pm_domain *domain,
59a3d0c390SChristian Gmeiner const struct etnaviv_pm_signal *signal)
60a3d0c390SChristian Gmeiner {
61a3d0c390SChristian Gmeiner u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
62a3d0c390SChristian Gmeiner u32 value = 0;
63a3d0c390SChristian Gmeiner unsigned i;
64a3d0c390SChristian Gmeiner
65a3d0c390SChristian Gmeiner for (i = 0; i < gpu->identity.pixel_pipes; i++) {
66*a5cafb90SChristian Gmeiner pipe_select(gpu, clock, i);
67658690d8SChristian Gmeiner value += perf_reg_read(gpu, domain, signal);
68a3d0c390SChristian Gmeiner }
69a3d0c390SChristian Gmeiner
70a3d0c390SChristian Gmeiner /* switch back to pixel pipe 0 to prevent GPU hang */
71*a5cafb90SChristian Gmeiner pipe_select(gpu, clock, 0);
72a3d0c390SChristian Gmeiner
73a3d0c390SChristian Gmeiner return value;
74a3d0c390SChristian Gmeiner }
75a3d0c390SChristian Gmeiner
pipe_reg_read(struct etnaviv_gpu * gpu,const struct etnaviv_pm_domain * domain,const struct etnaviv_pm_signal * signal)76bbab2be7SChristian Gmeiner static u32 pipe_reg_read(struct etnaviv_gpu *gpu,
77bbab2be7SChristian Gmeiner const struct etnaviv_pm_domain *domain,
78bbab2be7SChristian Gmeiner const struct etnaviv_pm_signal *signal)
79bbab2be7SChristian Gmeiner {
80bbab2be7SChristian Gmeiner u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
81bbab2be7SChristian Gmeiner u32 value = 0;
82bbab2be7SChristian Gmeiner unsigned i;
83bbab2be7SChristian Gmeiner
84bbab2be7SChristian Gmeiner for (i = 0; i < gpu->identity.pixel_pipes; i++) {
85*a5cafb90SChristian Gmeiner pipe_select(gpu, clock, i);
86bbab2be7SChristian Gmeiner value += gpu_read(gpu, signal->data);
87bbab2be7SChristian Gmeiner }
88bbab2be7SChristian Gmeiner
89bbab2be7SChristian Gmeiner /* switch back to pixel pipe 0 to prevent GPU hang */
90*a5cafb90SChristian Gmeiner pipe_select(gpu, clock, 0);
91bbab2be7SChristian Gmeiner
92bbab2be7SChristian Gmeiner return value;
93bbab2be7SChristian Gmeiner }
94bbab2be7SChristian Gmeiner
hi_total_cycle_read(struct etnaviv_gpu * gpu,const struct etnaviv_pm_domain * domain,const struct etnaviv_pm_signal * signal)9515ff4a7bSChristian Gmeiner static u32 hi_total_cycle_read(struct etnaviv_gpu *gpu,
9615ff4a7bSChristian Gmeiner const struct etnaviv_pm_domain *domain,
9715ff4a7bSChristian Gmeiner const struct etnaviv_pm_signal *signal)
9815ff4a7bSChristian Gmeiner {
9915ff4a7bSChristian Gmeiner u32 reg = VIVS_HI_PROFILE_TOTAL_CYCLES;
10015ff4a7bSChristian Gmeiner
10115ff4a7bSChristian Gmeiner if (gpu->identity.model == chipModel_GC880 ||
10215ff4a7bSChristian Gmeiner gpu->identity.model == chipModel_GC2000 ||
10315ff4a7bSChristian Gmeiner gpu->identity.model == chipModel_GC2100)
10415ff4a7bSChristian Gmeiner reg = VIVS_MC_PROFILE_CYCLE_COUNTER;
10515ff4a7bSChristian Gmeiner
10615ff4a7bSChristian Gmeiner return gpu_read(gpu, reg);
10715ff4a7bSChristian Gmeiner }
10815ff4a7bSChristian Gmeiner
hi_total_idle_cycle_read(struct etnaviv_gpu * gpu,const struct etnaviv_pm_domain * domain,const struct etnaviv_pm_signal * signal)10915ff4a7bSChristian Gmeiner static u32 hi_total_idle_cycle_read(struct etnaviv_gpu *gpu,
11015ff4a7bSChristian Gmeiner const struct etnaviv_pm_domain *domain,
11115ff4a7bSChristian Gmeiner const struct etnaviv_pm_signal *signal)
11215ff4a7bSChristian Gmeiner {
11315ff4a7bSChristian Gmeiner u32 reg = VIVS_HI_PROFILE_IDLE_CYCLES;
11415ff4a7bSChristian Gmeiner
11515ff4a7bSChristian Gmeiner if (gpu->identity.model == chipModel_GC880 ||
11615ff4a7bSChristian Gmeiner gpu->identity.model == chipModel_GC2000 ||
11715ff4a7bSChristian Gmeiner gpu->identity.model == chipModel_GC2100)
11815ff4a7bSChristian Gmeiner reg = VIVS_HI_PROFILE_TOTAL_CYCLES;
11915ff4a7bSChristian Gmeiner
12015ff4a7bSChristian Gmeiner return gpu_read(gpu, reg);
12115ff4a7bSChristian Gmeiner }
12215ff4a7bSChristian Gmeiner
1239e2c2e27SChristian Gmeiner static const struct etnaviv_pm_domain doms_3d[] = {
12433deff0aSChristian Gmeiner {
12533deff0aSChristian Gmeiner .name = "HI",
12633deff0aSChristian Gmeiner .profile_read = VIVS_MC_PROFILE_HI_READ,
12733deff0aSChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG2,
128bbab2be7SChristian Gmeiner .nr_signals = 7,
12933deff0aSChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
13033deff0aSChristian Gmeiner {
131bbab2be7SChristian Gmeiner "TOTAL_READ_BYTES8",
132bbab2be7SChristian Gmeiner VIVS_HI_PROFILE_READ_BYTES8,
133bbab2be7SChristian Gmeiner &pipe_reg_read,
134bbab2be7SChristian Gmeiner },
135bbab2be7SChristian Gmeiner {
136bbab2be7SChristian Gmeiner "TOTAL_WRITE_BYTES8",
137bbab2be7SChristian Gmeiner VIVS_HI_PROFILE_WRITE_BYTES8,
138bbab2be7SChristian Gmeiner &pipe_reg_read,
139bbab2be7SChristian Gmeiner },
140bbab2be7SChristian Gmeiner {
14133deff0aSChristian Gmeiner "TOTAL_CYCLES",
14215ff4a7bSChristian Gmeiner 0,
14315ff4a7bSChristian Gmeiner &hi_total_cycle_read
14433deff0aSChristian Gmeiner },
14533deff0aSChristian Gmeiner {
14633deff0aSChristian Gmeiner "IDLE_CYCLES",
14715ff4a7bSChristian Gmeiner 0,
14815ff4a7bSChristian Gmeiner &hi_total_idle_cycle_read
14933deff0aSChristian Gmeiner },
15033deff0aSChristian Gmeiner {
15133deff0aSChristian Gmeiner "AXI_CYCLES_READ_REQUEST_STALLED",
15233deff0aSChristian Gmeiner VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED,
15333deff0aSChristian Gmeiner &perf_reg_read
15433deff0aSChristian Gmeiner },
15533deff0aSChristian Gmeiner {
15633deff0aSChristian Gmeiner "AXI_CYCLES_WRITE_REQUEST_STALLED",
15733deff0aSChristian Gmeiner VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
15833deff0aSChristian Gmeiner &perf_reg_read
15933deff0aSChristian Gmeiner },
16033deff0aSChristian Gmeiner {
16133deff0aSChristian Gmeiner "AXI_CYCLES_WRITE_DATA_STALLED",
16233deff0aSChristian Gmeiner VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED,
16333deff0aSChristian Gmeiner &perf_reg_read
16433deff0aSChristian Gmeiner }
16533deff0aSChristian Gmeiner }
166a3d0c390SChristian Gmeiner },
167a3d0c390SChristian Gmeiner {
168a3d0c390SChristian Gmeiner .name = "PE",
169a3d0c390SChristian Gmeiner .profile_read = VIVS_MC_PROFILE_PE_READ,
170a3d0c390SChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG0,
171f5fd9fd4SDan Carpenter .nr_signals = 4,
172a3d0c390SChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
173a3d0c390SChristian Gmeiner {
174a3d0c390SChristian Gmeiner "PIXEL_COUNT_KILLED_BY_COLOR_PIPE",
175a3d0c390SChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
17677dfb36aSChristian Gmeiner &pipe_perf_reg_read
177a3d0c390SChristian Gmeiner },
178a3d0c390SChristian Gmeiner {
179a3d0c390SChristian Gmeiner "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE",
180a3d0c390SChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
18177dfb36aSChristian Gmeiner &pipe_perf_reg_read
182a3d0c390SChristian Gmeiner },
183a3d0c390SChristian Gmeiner {
184a3d0c390SChristian Gmeiner "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE",
185a3d0c390SChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
18677dfb36aSChristian Gmeiner &pipe_perf_reg_read
187a3d0c390SChristian Gmeiner },
188a3d0c390SChristian Gmeiner {
189a3d0c390SChristian Gmeiner "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE",
190a3d0c390SChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
19177dfb36aSChristian Gmeiner &pipe_perf_reg_read
192a3d0c390SChristian Gmeiner }
193a3d0c390SChristian Gmeiner }
19498b2482eSChristian Gmeiner },
19598b2482eSChristian Gmeiner {
19698b2482eSChristian Gmeiner .name = "SH",
19798b2482eSChristian Gmeiner .profile_read = VIVS_MC_PROFILE_SH_READ,
19898b2482eSChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG0,
19998b2482eSChristian Gmeiner .nr_signals = 9,
20098b2482eSChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
20198b2482eSChristian Gmeiner {
20298b2482eSChristian Gmeiner "SHADER_CYCLES",
20398b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES,
20498b2482eSChristian Gmeiner &perf_reg_read
20598b2482eSChristian Gmeiner },
20698b2482eSChristian Gmeiner {
20798b2482eSChristian Gmeiner "PS_INST_COUNTER",
20898b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER,
20998b2482eSChristian Gmeiner &perf_reg_read
21098b2482eSChristian Gmeiner },
21198b2482eSChristian Gmeiner {
21298b2482eSChristian Gmeiner "RENDERED_PIXEL_COUNTER",
21398b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER,
21498b2482eSChristian Gmeiner &perf_reg_read
21598b2482eSChristian Gmeiner },
21698b2482eSChristian Gmeiner {
21798b2482eSChristian Gmeiner "VS_INST_COUNTER",
21898b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER,
21977dfb36aSChristian Gmeiner &pipe_perf_reg_read
22098b2482eSChristian Gmeiner },
22198b2482eSChristian Gmeiner {
22298b2482eSChristian Gmeiner "RENDERED_VERTICE_COUNTER",
22398b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER,
22477dfb36aSChristian Gmeiner &pipe_perf_reg_read
22598b2482eSChristian Gmeiner },
22698b2482eSChristian Gmeiner {
22798b2482eSChristian Gmeiner "VTX_BRANCH_INST_COUNTER",
22898b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER,
22977dfb36aSChristian Gmeiner &pipe_perf_reg_read
23098b2482eSChristian Gmeiner },
23198b2482eSChristian Gmeiner {
23298b2482eSChristian Gmeiner "VTX_TEXLD_INST_COUNTER",
23398b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER,
23477dfb36aSChristian Gmeiner &pipe_perf_reg_read
23598b2482eSChristian Gmeiner },
23698b2482eSChristian Gmeiner {
23798b2482eSChristian Gmeiner "PXL_BRANCH_INST_COUNTER",
23898b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER,
23977dfb36aSChristian Gmeiner &pipe_perf_reg_read
24098b2482eSChristian Gmeiner },
24198b2482eSChristian Gmeiner {
24298b2482eSChristian Gmeiner "PXL_TEXLD_INST_COUNTER",
24398b2482eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER,
24477dfb36aSChristian Gmeiner &pipe_perf_reg_read
24598b2482eSChristian Gmeiner }
24698b2482eSChristian Gmeiner }
247c3787ff6SChristian Gmeiner },
248c3787ff6SChristian Gmeiner {
249c3787ff6SChristian Gmeiner .name = "PA",
250c3787ff6SChristian Gmeiner .profile_read = VIVS_MC_PROFILE_PA_READ,
251c3787ff6SChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG1,
252c3787ff6SChristian Gmeiner .nr_signals = 6,
253c3787ff6SChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
254c3787ff6SChristian Gmeiner {
255c3787ff6SChristian Gmeiner "INPUT_VTX_COUNTER",
256c3787ff6SChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER,
257c3787ff6SChristian Gmeiner &perf_reg_read
258c3787ff6SChristian Gmeiner },
259c3787ff6SChristian Gmeiner {
260c3787ff6SChristian Gmeiner "INPUT_PRIM_COUNTER",
261c3787ff6SChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER,
262c3787ff6SChristian Gmeiner &perf_reg_read
263c3787ff6SChristian Gmeiner },
264c3787ff6SChristian Gmeiner {
265c3787ff6SChristian Gmeiner "OUTPUT_PRIM_COUNTER",
266c3787ff6SChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER,
267c3787ff6SChristian Gmeiner &perf_reg_read
268c3787ff6SChristian Gmeiner },
269c3787ff6SChristian Gmeiner {
270c3787ff6SChristian Gmeiner "DEPTH_CLIPPED_COUNTER",
271c3787ff6SChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER,
27277dfb36aSChristian Gmeiner &pipe_perf_reg_read
273c3787ff6SChristian Gmeiner },
274c3787ff6SChristian Gmeiner {
275c3787ff6SChristian Gmeiner "TRIVIAL_REJECTED_COUNTER",
276c3787ff6SChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER,
27777dfb36aSChristian Gmeiner &pipe_perf_reg_read
278c3787ff6SChristian Gmeiner },
279c3787ff6SChristian Gmeiner {
280c3787ff6SChristian Gmeiner "CULLED_COUNTER",
281c3787ff6SChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER,
28277dfb36aSChristian Gmeiner &pipe_perf_reg_read
283c3787ff6SChristian Gmeiner }
284c3787ff6SChristian Gmeiner }
285a515264cSChristian Gmeiner },
286a515264cSChristian Gmeiner {
287a515264cSChristian Gmeiner .name = "SE",
288a515264cSChristian Gmeiner .profile_read = VIVS_MC_PROFILE_SE_READ,
289a515264cSChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG1,
290a515264cSChristian Gmeiner .nr_signals = 2,
291a515264cSChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
292a515264cSChristian Gmeiner {
293a515264cSChristian Gmeiner "CULLED_TRIANGLE_COUNT",
294a515264cSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT,
295a515264cSChristian Gmeiner &perf_reg_read
296a515264cSChristian Gmeiner },
297a515264cSChristian Gmeiner {
298a515264cSChristian Gmeiner "CULLED_LINES_COUNT",
299a515264cSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT,
300a515264cSChristian Gmeiner &perf_reg_read
301a515264cSChristian Gmeiner }
302a515264cSChristian Gmeiner }
30391a9a17bSChristian Gmeiner },
30491a9a17bSChristian Gmeiner {
30591a9a17bSChristian Gmeiner .name = "RA",
30691a9a17bSChristian Gmeiner .profile_read = VIVS_MC_PROFILE_RA_READ,
30791a9a17bSChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG1,
30891a9a17bSChristian Gmeiner .nr_signals = 7,
30991a9a17bSChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
31091a9a17bSChristian Gmeiner {
31191a9a17bSChristian Gmeiner "VALID_PIXEL_COUNT",
31291a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT,
31391a9a17bSChristian Gmeiner &perf_reg_read
31491a9a17bSChristian Gmeiner },
31591a9a17bSChristian Gmeiner {
31691a9a17bSChristian Gmeiner "TOTAL_QUAD_COUNT",
31791a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT,
31891a9a17bSChristian Gmeiner &perf_reg_read
31991a9a17bSChristian Gmeiner },
32091a9a17bSChristian Gmeiner {
32191a9a17bSChristian Gmeiner "VALID_QUAD_COUNT_AFTER_EARLY_Z",
32291a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
32391a9a17bSChristian Gmeiner &perf_reg_read
32491a9a17bSChristian Gmeiner },
32591a9a17bSChristian Gmeiner {
32691a9a17bSChristian Gmeiner "TOTAL_PRIMITIVE_COUNT",
32791a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT,
32891a9a17bSChristian Gmeiner &perf_reg_read
32991a9a17bSChristian Gmeiner },
33091a9a17bSChristian Gmeiner {
33191a9a17bSChristian Gmeiner "PIPE_CACHE_MISS_COUNTER",
33291a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER,
33391a9a17bSChristian Gmeiner &perf_reg_read
33491a9a17bSChristian Gmeiner },
33591a9a17bSChristian Gmeiner {
33691a9a17bSChristian Gmeiner "PREFETCH_CACHE_MISS_COUNTER",
33791a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER,
33891a9a17bSChristian Gmeiner &perf_reg_read
33991a9a17bSChristian Gmeiner },
34091a9a17bSChristian Gmeiner {
34191a9a17bSChristian Gmeiner "CULLED_QUAD_COUNT",
34291a9a17bSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT,
34391a9a17bSChristian Gmeiner &perf_reg_read
34491a9a17bSChristian Gmeiner }
34591a9a17bSChristian Gmeiner }
3469646025eSChristian Gmeiner },
3479646025eSChristian Gmeiner {
3489646025eSChristian Gmeiner .name = "TX",
3499646025eSChristian Gmeiner .profile_read = VIVS_MC_PROFILE_TX_READ,
3509646025eSChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG1,
3519646025eSChristian Gmeiner .nr_signals = 9,
3529646025eSChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
3539646025eSChristian Gmeiner {
3549646025eSChristian Gmeiner "TOTAL_BILINEAR_REQUESTS",
3559646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS,
3569646025eSChristian Gmeiner &perf_reg_read
3579646025eSChristian Gmeiner },
3589646025eSChristian Gmeiner {
3599646025eSChristian Gmeiner "TOTAL_TRILINEAR_REQUESTS",
3609646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS,
3619646025eSChristian Gmeiner &perf_reg_read
3629646025eSChristian Gmeiner },
3639646025eSChristian Gmeiner {
3649646025eSChristian Gmeiner "TOTAL_DISCARDED_TEXTURE_REQUESTS",
3659646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
3669646025eSChristian Gmeiner &perf_reg_read
3679646025eSChristian Gmeiner },
3689646025eSChristian Gmeiner {
3699646025eSChristian Gmeiner "TOTAL_TEXTURE_REQUESTS",
3709646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS,
3719646025eSChristian Gmeiner &perf_reg_read
3729646025eSChristian Gmeiner },
3739646025eSChristian Gmeiner {
3749646025eSChristian Gmeiner "MEM_READ_COUNT",
3759646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT,
3769646025eSChristian Gmeiner &perf_reg_read
3779646025eSChristian Gmeiner },
3789646025eSChristian Gmeiner {
3799646025eSChristian Gmeiner "MEM_READ_IN_8B_COUNT",
3809646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT,
3819646025eSChristian Gmeiner &perf_reg_read
3829646025eSChristian Gmeiner },
3839646025eSChristian Gmeiner {
3849646025eSChristian Gmeiner "CACHE_MISS_COUNT",
3859646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT,
3869646025eSChristian Gmeiner &perf_reg_read
3879646025eSChristian Gmeiner },
3889646025eSChristian Gmeiner {
3899646025eSChristian Gmeiner "CACHE_HIT_TEXEL_COUNT",
3909646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT,
3919646025eSChristian Gmeiner &perf_reg_read
3929646025eSChristian Gmeiner },
3939646025eSChristian Gmeiner {
3949646025eSChristian Gmeiner "CACHE_MISS_TEXEL_COUNT",
3959646025eSChristian Gmeiner VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT,
3969646025eSChristian Gmeiner &perf_reg_read
3979646025eSChristian Gmeiner }
3989646025eSChristian Gmeiner }
39949168ee9SChristian Gmeiner },
40049168ee9SChristian Gmeiner {
40149168ee9SChristian Gmeiner .name = "MC",
40249168ee9SChristian Gmeiner .profile_read = VIVS_MC_PROFILE_MC_READ,
40349168ee9SChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG2,
40449168ee9SChristian Gmeiner .nr_signals = 3,
40549168ee9SChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
40649168ee9SChristian Gmeiner {
40749168ee9SChristian Gmeiner "TOTAL_READ_REQ_8B_FROM_PIPELINE",
40849168ee9SChristian Gmeiner VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
40949168ee9SChristian Gmeiner &perf_reg_read
41049168ee9SChristian Gmeiner },
41149168ee9SChristian Gmeiner {
41249168ee9SChristian Gmeiner "TOTAL_READ_REQ_8B_FROM_IP",
41349168ee9SChristian Gmeiner VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP,
41449168ee9SChristian Gmeiner &perf_reg_read
41549168ee9SChristian Gmeiner },
41649168ee9SChristian Gmeiner {
41749168ee9SChristian Gmeiner "TOTAL_WRITE_REQ_8B_FROM_PIPELINE",
41849168ee9SChristian Gmeiner VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
41949168ee9SChristian Gmeiner &perf_reg_read
42049168ee9SChristian Gmeiner }
42149168ee9SChristian Gmeiner }
42233deff0aSChristian Gmeiner }
4239e2c2e27SChristian Gmeiner };
4249e2c2e27SChristian Gmeiner
4259e2c2e27SChristian Gmeiner static const struct etnaviv_pm_domain doms_2d[] = {
426a3d0c390SChristian Gmeiner {
427a3d0c390SChristian Gmeiner .name = "PE",
428a3d0c390SChristian Gmeiner .profile_read = VIVS_MC_PROFILE_PE_READ,
429a3d0c390SChristian Gmeiner .profile_config = VIVS_MC_PROFILE_CONFIG0,
430a3d0c390SChristian Gmeiner .nr_signals = 1,
431a3d0c390SChristian Gmeiner .signal = (const struct etnaviv_pm_signal[]) {
432a3d0c390SChristian Gmeiner {
433a3d0c390SChristian Gmeiner "PIXELS_RENDERED_2D",
434a3d0c390SChristian Gmeiner VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D,
43577dfb36aSChristian Gmeiner &pipe_perf_reg_read
436a3d0c390SChristian Gmeiner }
437a3d0c390SChristian Gmeiner }
438a3d0c390SChristian Gmeiner }
4399e2c2e27SChristian Gmeiner };
4409e2c2e27SChristian Gmeiner
4419e2c2e27SChristian Gmeiner static const struct etnaviv_pm_domain doms_vg[] = {
4429e2c2e27SChristian Gmeiner };
4439e2c2e27SChristian Gmeiner
4449e2c2e27SChristian Gmeiner static const struct etnaviv_pm_domain_meta doms_meta[] = {
4459e2c2e27SChristian Gmeiner {
446ed1dd899SChristian Gmeiner .feature = chipFeatures_PIPE_3D,
4479e2c2e27SChristian Gmeiner .nr_domains = ARRAY_SIZE(doms_3d),
4489e2c2e27SChristian Gmeiner .domains = &doms_3d[0]
4499e2c2e27SChristian Gmeiner },
4509e2c2e27SChristian Gmeiner {
451ed1dd899SChristian Gmeiner .feature = chipFeatures_PIPE_2D,
4529e2c2e27SChristian Gmeiner .nr_domains = ARRAY_SIZE(doms_2d),
4539e2c2e27SChristian Gmeiner .domains = &doms_2d[0]
4549e2c2e27SChristian Gmeiner },
4559e2c2e27SChristian Gmeiner {
456ed1dd899SChristian Gmeiner .feature = chipFeatures_PIPE_VG,
4579e2c2e27SChristian Gmeiner .nr_domains = ARRAY_SIZE(doms_vg),
4589e2c2e27SChristian Gmeiner .domains = &doms_vg[0]
4599e2c2e27SChristian Gmeiner }
4609e2c2e27SChristian Gmeiner };
4619e2c2e27SChristian Gmeiner
num_pm_domains(const struct etnaviv_gpu * gpu)462ed1dd899SChristian Gmeiner static unsigned int num_pm_domains(const struct etnaviv_gpu *gpu)
463ed1dd899SChristian Gmeiner {
464ed1dd899SChristian Gmeiner unsigned int num = 0, i;
465ed1dd899SChristian Gmeiner
466ed1dd899SChristian Gmeiner for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
467ed1dd899SChristian Gmeiner const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];
468ed1dd899SChristian Gmeiner
469ed1dd899SChristian Gmeiner if (gpu->identity.features & meta->feature)
470ed1dd899SChristian Gmeiner num += meta->nr_domains;
471ed1dd899SChristian Gmeiner }
472ed1dd899SChristian Gmeiner
473ed1dd899SChristian Gmeiner return num;
474ed1dd899SChristian Gmeiner }
475ed1dd899SChristian Gmeiner
pm_domain(const struct etnaviv_gpu * gpu,unsigned int index)476ed1dd899SChristian Gmeiner static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu,
477ed1dd899SChristian Gmeiner unsigned int index)
478ed1dd899SChristian Gmeiner {
479ed1dd899SChristian Gmeiner const struct etnaviv_pm_domain *domain = NULL;
480ed1dd899SChristian Gmeiner unsigned int offset = 0, i;
481ed1dd899SChristian Gmeiner
482ed1dd899SChristian Gmeiner for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
483ed1dd899SChristian Gmeiner const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];
484ed1dd899SChristian Gmeiner
485ed1dd899SChristian Gmeiner if (!(gpu->identity.features & meta->feature))
486ed1dd899SChristian Gmeiner continue;
487ed1dd899SChristian Gmeiner
48840b697e2SChristian Gmeiner if (index - offset >= meta->nr_domains) {
489ed1dd899SChristian Gmeiner offset += meta->nr_domains;
490ed1dd899SChristian Gmeiner continue;
491ed1dd899SChristian Gmeiner }
492ed1dd899SChristian Gmeiner
493ed1dd899SChristian Gmeiner domain = meta->domains + (index - offset);
494ed1dd899SChristian Gmeiner }
495ed1dd899SChristian Gmeiner
496ed1dd899SChristian Gmeiner return domain;
497ed1dd899SChristian Gmeiner }
498ed1dd899SChristian Gmeiner
etnaviv_pm_query_dom(struct etnaviv_gpu * gpu,struct drm_etnaviv_pm_domain * domain)4999e2c2e27SChristian Gmeiner int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
5009e2c2e27SChristian Gmeiner struct drm_etnaviv_pm_domain *domain)
5019e2c2e27SChristian Gmeiner {
502ed1dd899SChristian Gmeiner const unsigned int nr_domains = num_pm_domains(gpu);
5039e2c2e27SChristian Gmeiner const struct etnaviv_pm_domain *dom;
5049e2c2e27SChristian Gmeiner
505ed1dd899SChristian Gmeiner if (domain->iter >= nr_domains)
5069e2c2e27SChristian Gmeiner return -EINVAL;
5079e2c2e27SChristian Gmeiner
508ed1dd899SChristian Gmeiner dom = pm_domain(gpu, domain->iter);
509ed1dd899SChristian Gmeiner if (!dom)
510ed1dd899SChristian Gmeiner return -EINVAL;
5119e2c2e27SChristian Gmeiner
5129e2c2e27SChristian Gmeiner domain->id = domain->iter;
5139e2c2e27SChristian Gmeiner domain->nr_signals = dom->nr_signals;
5149e2c2e27SChristian Gmeiner strncpy(domain->name, dom->name, sizeof(domain->name));
5159e2c2e27SChristian Gmeiner
5169e2c2e27SChristian Gmeiner domain->iter++;
517ed1dd899SChristian Gmeiner if (domain->iter == nr_domains)
5189e2c2e27SChristian Gmeiner domain->iter = 0xff;
5199e2c2e27SChristian Gmeiner
5209e2c2e27SChristian Gmeiner return 0;
5219e2c2e27SChristian Gmeiner }
5229e2c2e27SChristian Gmeiner
etnaviv_pm_query_sig(struct etnaviv_gpu * gpu,struct drm_etnaviv_pm_signal * signal)5239e2c2e27SChristian Gmeiner int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
5249e2c2e27SChristian Gmeiner struct drm_etnaviv_pm_signal *signal)
5259e2c2e27SChristian Gmeiner {
526ed1dd899SChristian Gmeiner const unsigned int nr_domains = num_pm_domains(gpu);
5279e2c2e27SChristian Gmeiner const struct etnaviv_pm_domain *dom;
5289e2c2e27SChristian Gmeiner const struct etnaviv_pm_signal *sig;
5299e2c2e27SChristian Gmeiner
530ed1dd899SChristian Gmeiner if (signal->domain >= nr_domains)
5319e2c2e27SChristian Gmeiner return -EINVAL;
5329e2c2e27SChristian Gmeiner
533ed1dd899SChristian Gmeiner dom = pm_domain(gpu, signal->domain);
534ed1dd899SChristian Gmeiner if (!dom)
535ed1dd899SChristian Gmeiner return -EINVAL;
5369e2c2e27SChristian Gmeiner
537f5fd9fd4SDan Carpenter if (signal->iter >= dom->nr_signals)
5389e2c2e27SChristian Gmeiner return -EINVAL;
5399e2c2e27SChristian Gmeiner
5409e2c2e27SChristian Gmeiner sig = &dom->signal[signal->iter];
5419e2c2e27SChristian Gmeiner
5429e2c2e27SChristian Gmeiner signal->id = signal->iter;
5439e2c2e27SChristian Gmeiner strncpy(signal->name, sig->name, sizeof(signal->name));
5449e2c2e27SChristian Gmeiner
5459e2c2e27SChristian Gmeiner signal->iter++;
5469e2c2e27SChristian Gmeiner if (signal->iter == dom->nr_signals)
5479e2c2e27SChristian Gmeiner signal->iter = 0xffff;
5489e2c2e27SChristian Gmeiner
5499e2c2e27SChristian Gmeiner return 0;
5509e2c2e27SChristian Gmeiner }
55146df52cdSChristian Gmeiner
etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr * r,u32 exec_state)55246df52cdSChristian Gmeiner int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,
55346df52cdSChristian Gmeiner u32 exec_state)
55446df52cdSChristian Gmeiner {
55546df52cdSChristian Gmeiner const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
55646df52cdSChristian Gmeiner const struct etnaviv_pm_domain *dom;
55746df52cdSChristian Gmeiner
55846df52cdSChristian Gmeiner if (r->domain >= meta->nr_domains)
55946df52cdSChristian Gmeiner return -EINVAL;
56046df52cdSChristian Gmeiner
56146df52cdSChristian Gmeiner dom = meta->domains + r->domain;
56246df52cdSChristian Gmeiner
563f5fd9fd4SDan Carpenter if (r->signal >= dom->nr_signals)
56446df52cdSChristian Gmeiner return -EINVAL;
56546df52cdSChristian Gmeiner
56646df52cdSChristian Gmeiner return 0;
56746df52cdSChristian Gmeiner }
568249300c7SChristian Gmeiner
etnaviv_perfmon_process(struct etnaviv_gpu * gpu,const struct etnaviv_perfmon_request * pmr,u32 exec_state)569249300c7SChristian Gmeiner void etnaviv_perfmon_process(struct etnaviv_gpu *gpu,
5707a9c0fe2SLucas Stach const struct etnaviv_perfmon_request *pmr, u32 exec_state)
571249300c7SChristian Gmeiner {
5727a9c0fe2SLucas Stach const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
573249300c7SChristian Gmeiner const struct etnaviv_pm_domain *dom;
574249300c7SChristian Gmeiner const struct etnaviv_pm_signal *sig;
575249300c7SChristian Gmeiner u32 *bo = pmr->bo_vma;
576249300c7SChristian Gmeiner u32 val;
577249300c7SChristian Gmeiner
578249300c7SChristian Gmeiner dom = meta->domains + pmr->domain;
579249300c7SChristian Gmeiner sig = &dom->signal[pmr->signal];
580249300c7SChristian Gmeiner val = sig->sample(gpu, dom, sig);
581249300c7SChristian Gmeiner
582249300c7SChristian Gmeiner *(bo + pmr->offset) = val;
583249300c7SChristian Gmeiner }
584