18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Etnaviv Project
48c2ecf20Sopenharmony_ci * Copyright (C) 2017 Zodiac Inflight Innovations
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include "common.xml.h"
88c2ecf20Sopenharmony_ci#include "etnaviv_gpu.h"
98c2ecf20Sopenharmony_ci#include "etnaviv_perfmon.h"
108c2ecf20Sopenharmony_ci#include "state_hi.xml.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_cistruct etnaviv_pm_domain;
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistruct etnaviv_pm_signal {
158c2ecf20Sopenharmony_ci	char name[64];
168c2ecf20Sopenharmony_ci	u32 data;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	u32 (*sample)(struct etnaviv_gpu *gpu,
198c2ecf20Sopenharmony_ci		      const struct etnaviv_pm_domain *domain,
208c2ecf20Sopenharmony_ci		      const struct etnaviv_pm_signal *signal);
218c2ecf20Sopenharmony_ci};
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_cistruct etnaviv_pm_domain {
248c2ecf20Sopenharmony_ci	char name[64];
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	/* profile register */
278c2ecf20Sopenharmony_ci	u32 profile_read;
288c2ecf20Sopenharmony_ci	u32 profile_config;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	u8 nr_signals;
318c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *signal;
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistruct etnaviv_pm_domain_meta {
358c2ecf20Sopenharmony_ci	unsigned int feature;
368c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *domains;
378c2ecf20Sopenharmony_ci	u32 nr_domains;
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistatic u32 perf_reg_read(struct etnaviv_gpu *gpu,
418c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *domain,
428c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *signal)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	gpu_write(gpu, domain->profile_config, signal->data);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	return gpu_read(gpu, domain->profile_read);
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic u32 pipe_reg_read(struct etnaviv_gpu *gpu,
508c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *domain,
518c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *signal)
528c2ecf20Sopenharmony_ci{
538c2ecf20Sopenharmony_ci	u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
548c2ecf20Sopenharmony_ci	u32 value = 0;
558c2ecf20Sopenharmony_ci	unsigned i;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	for (i = 0; i < gpu->identity.pixel_pipes; i++) {
588c2ecf20Sopenharmony_ci		clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
598c2ecf20Sopenharmony_ci		clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(i);
608c2ecf20Sopenharmony_ci		gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
618c2ecf20Sopenharmony_ci		gpu_write(gpu, domain->profile_config, signal->data);
628c2ecf20Sopenharmony_ci		value += gpu_read(gpu, domain->profile_read);
638c2ecf20Sopenharmony_ci	}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/* switch back to pixel pipe 0 to prevent GPU hang */
668c2ecf20Sopenharmony_ci	clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
678c2ecf20Sopenharmony_ci	clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(0);
688c2ecf20Sopenharmony_ci	gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	return value;
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic u32 hi_total_cycle_read(struct etnaviv_gpu *gpu,
748c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *domain,
758c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *signal)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	u32 reg = VIVS_HI_PROFILE_TOTAL_CYCLES;
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	if (gpu->identity.model == chipModel_GC880 ||
808c2ecf20Sopenharmony_ci		gpu->identity.model == chipModel_GC2000 ||
818c2ecf20Sopenharmony_ci		gpu->identity.model == chipModel_GC2100)
828c2ecf20Sopenharmony_ci		reg = VIVS_MC_PROFILE_CYCLE_COUNTER;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	return gpu_read(gpu, reg);
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic u32 hi_total_idle_cycle_read(struct etnaviv_gpu *gpu,
888c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *domain,
898c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *signal)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	u32 reg = VIVS_HI_PROFILE_IDLE_CYCLES;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	if (gpu->identity.model == chipModel_GC880 ||
948c2ecf20Sopenharmony_ci		gpu->identity.model == chipModel_GC2000 ||
958c2ecf20Sopenharmony_ci		gpu->identity.model == chipModel_GC2100)
968c2ecf20Sopenharmony_ci		reg = VIVS_HI_PROFILE_TOTAL_CYCLES;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	return gpu_read(gpu, reg);
998c2ecf20Sopenharmony_ci}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic const struct etnaviv_pm_domain doms_3d[] = {
1028c2ecf20Sopenharmony_ci	{
1038c2ecf20Sopenharmony_ci		.name = "HI",
1048c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_HI_READ,
1058c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG2,
1068c2ecf20Sopenharmony_ci		.nr_signals = 5,
1078c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
1088c2ecf20Sopenharmony_ci			{
1098c2ecf20Sopenharmony_ci				"TOTAL_CYCLES",
1108c2ecf20Sopenharmony_ci				0,
1118c2ecf20Sopenharmony_ci				&hi_total_cycle_read
1128c2ecf20Sopenharmony_ci			},
1138c2ecf20Sopenharmony_ci			{
1148c2ecf20Sopenharmony_ci				"IDLE_CYCLES",
1158c2ecf20Sopenharmony_ci				0,
1168c2ecf20Sopenharmony_ci				&hi_total_idle_cycle_read
1178c2ecf20Sopenharmony_ci			},
1188c2ecf20Sopenharmony_ci			{
1198c2ecf20Sopenharmony_ci				"AXI_CYCLES_READ_REQUEST_STALLED",
1208c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED,
1218c2ecf20Sopenharmony_ci				&perf_reg_read
1228c2ecf20Sopenharmony_ci			},
1238c2ecf20Sopenharmony_ci			{
1248c2ecf20Sopenharmony_ci				"AXI_CYCLES_WRITE_REQUEST_STALLED",
1258c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
1268c2ecf20Sopenharmony_ci				&perf_reg_read
1278c2ecf20Sopenharmony_ci			},
1288c2ecf20Sopenharmony_ci			{
1298c2ecf20Sopenharmony_ci				"AXI_CYCLES_WRITE_DATA_STALLED",
1308c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED,
1318c2ecf20Sopenharmony_ci				&perf_reg_read
1328c2ecf20Sopenharmony_ci			}
1338c2ecf20Sopenharmony_ci		}
1348c2ecf20Sopenharmony_ci	},
1358c2ecf20Sopenharmony_ci	{
1368c2ecf20Sopenharmony_ci		.name = "PE",
1378c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_PE_READ,
1388c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG0,
1398c2ecf20Sopenharmony_ci		.nr_signals = 4,
1408c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
1418c2ecf20Sopenharmony_ci			{
1428c2ecf20Sopenharmony_ci				"PIXEL_COUNT_KILLED_BY_COLOR_PIPE",
1438c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
1448c2ecf20Sopenharmony_ci				&pipe_reg_read
1458c2ecf20Sopenharmony_ci			},
1468c2ecf20Sopenharmony_ci			{
1478c2ecf20Sopenharmony_ci				"PIXEL_COUNT_KILLED_BY_DEPTH_PIPE",
1488c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
1498c2ecf20Sopenharmony_ci				&pipe_reg_read
1508c2ecf20Sopenharmony_ci			},
1518c2ecf20Sopenharmony_ci			{
1528c2ecf20Sopenharmony_ci				"PIXEL_COUNT_DRAWN_BY_COLOR_PIPE",
1538c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
1548c2ecf20Sopenharmony_ci				&pipe_reg_read
1558c2ecf20Sopenharmony_ci			},
1568c2ecf20Sopenharmony_ci			{
1578c2ecf20Sopenharmony_ci				"PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE",
1588c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
1598c2ecf20Sopenharmony_ci				&pipe_reg_read
1608c2ecf20Sopenharmony_ci			}
1618c2ecf20Sopenharmony_ci		}
1628c2ecf20Sopenharmony_ci	},
1638c2ecf20Sopenharmony_ci	{
1648c2ecf20Sopenharmony_ci		.name = "SH",
1658c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_SH_READ,
1668c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG0,
1678c2ecf20Sopenharmony_ci		.nr_signals = 9,
1688c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
1698c2ecf20Sopenharmony_ci			{
1708c2ecf20Sopenharmony_ci				"SHADER_CYCLES",
1718c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES,
1728c2ecf20Sopenharmony_ci				&perf_reg_read
1738c2ecf20Sopenharmony_ci			},
1748c2ecf20Sopenharmony_ci			{
1758c2ecf20Sopenharmony_ci				"PS_INST_COUNTER",
1768c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER,
1778c2ecf20Sopenharmony_ci				&perf_reg_read
1788c2ecf20Sopenharmony_ci			},
1798c2ecf20Sopenharmony_ci			{
1808c2ecf20Sopenharmony_ci				"RENDERED_PIXEL_COUNTER",
1818c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER,
1828c2ecf20Sopenharmony_ci				&perf_reg_read
1838c2ecf20Sopenharmony_ci			},
1848c2ecf20Sopenharmony_ci			{
1858c2ecf20Sopenharmony_ci				"VS_INST_COUNTER",
1868c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER,
1878c2ecf20Sopenharmony_ci				&pipe_reg_read
1888c2ecf20Sopenharmony_ci			},
1898c2ecf20Sopenharmony_ci			{
1908c2ecf20Sopenharmony_ci				"RENDERED_VERTICE_COUNTER",
1918c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER,
1928c2ecf20Sopenharmony_ci				&pipe_reg_read
1938c2ecf20Sopenharmony_ci			},
1948c2ecf20Sopenharmony_ci			{
1958c2ecf20Sopenharmony_ci				"VTX_BRANCH_INST_COUNTER",
1968c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER,
1978c2ecf20Sopenharmony_ci				&pipe_reg_read
1988c2ecf20Sopenharmony_ci			},
1998c2ecf20Sopenharmony_ci			{
2008c2ecf20Sopenharmony_ci				"VTX_TEXLD_INST_COUNTER",
2018c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER,
2028c2ecf20Sopenharmony_ci				&pipe_reg_read
2038c2ecf20Sopenharmony_ci			},
2048c2ecf20Sopenharmony_ci			{
2058c2ecf20Sopenharmony_ci				"PXL_BRANCH_INST_COUNTER",
2068c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER,
2078c2ecf20Sopenharmony_ci				&pipe_reg_read
2088c2ecf20Sopenharmony_ci			},
2098c2ecf20Sopenharmony_ci			{
2108c2ecf20Sopenharmony_ci				"PXL_TEXLD_INST_COUNTER",
2118c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER,
2128c2ecf20Sopenharmony_ci				&pipe_reg_read
2138c2ecf20Sopenharmony_ci			}
2148c2ecf20Sopenharmony_ci		}
2158c2ecf20Sopenharmony_ci	},
2168c2ecf20Sopenharmony_ci	{
2178c2ecf20Sopenharmony_ci		.name = "PA",
2188c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_PA_READ,
2198c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG1,
2208c2ecf20Sopenharmony_ci		.nr_signals = 6,
2218c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
2228c2ecf20Sopenharmony_ci			{
2238c2ecf20Sopenharmony_ci				"INPUT_VTX_COUNTER",
2248c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER,
2258c2ecf20Sopenharmony_ci				&perf_reg_read
2268c2ecf20Sopenharmony_ci			},
2278c2ecf20Sopenharmony_ci			{
2288c2ecf20Sopenharmony_ci				"INPUT_PRIM_COUNTER",
2298c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER,
2308c2ecf20Sopenharmony_ci				&perf_reg_read
2318c2ecf20Sopenharmony_ci			},
2328c2ecf20Sopenharmony_ci			{
2338c2ecf20Sopenharmony_ci				"OUTPUT_PRIM_COUNTER",
2348c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER,
2358c2ecf20Sopenharmony_ci				&perf_reg_read
2368c2ecf20Sopenharmony_ci			},
2378c2ecf20Sopenharmony_ci			{
2388c2ecf20Sopenharmony_ci				"DEPTH_CLIPPED_COUNTER",
2398c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER,
2408c2ecf20Sopenharmony_ci				&pipe_reg_read
2418c2ecf20Sopenharmony_ci			},
2428c2ecf20Sopenharmony_ci			{
2438c2ecf20Sopenharmony_ci				"TRIVIAL_REJECTED_COUNTER",
2448c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER,
2458c2ecf20Sopenharmony_ci				&pipe_reg_read
2468c2ecf20Sopenharmony_ci			},
2478c2ecf20Sopenharmony_ci			{
2488c2ecf20Sopenharmony_ci				"CULLED_COUNTER",
2498c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER,
2508c2ecf20Sopenharmony_ci				&pipe_reg_read
2518c2ecf20Sopenharmony_ci			}
2528c2ecf20Sopenharmony_ci		}
2538c2ecf20Sopenharmony_ci	},
2548c2ecf20Sopenharmony_ci	{
2558c2ecf20Sopenharmony_ci		.name = "SE",
2568c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_SE_READ,
2578c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG1,
2588c2ecf20Sopenharmony_ci		.nr_signals = 2,
2598c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
2608c2ecf20Sopenharmony_ci			{
2618c2ecf20Sopenharmony_ci				"CULLED_TRIANGLE_COUNT",
2628c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT,
2638c2ecf20Sopenharmony_ci				&perf_reg_read
2648c2ecf20Sopenharmony_ci			},
2658c2ecf20Sopenharmony_ci			{
2668c2ecf20Sopenharmony_ci				"CULLED_LINES_COUNT",
2678c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT,
2688c2ecf20Sopenharmony_ci				&perf_reg_read
2698c2ecf20Sopenharmony_ci			}
2708c2ecf20Sopenharmony_ci		}
2718c2ecf20Sopenharmony_ci	},
2728c2ecf20Sopenharmony_ci	{
2738c2ecf20Sopenharmony_ci		.name = "RA",
2748c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_RA_READ,
2758c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG1,
2768c2ecf20Sopenharmony_ci		.nr_signals = 7,
2778c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
2788c2ecf20Sopenharmony_ci			{
2798c2ecf20Sopenharmony_ci				"VALID_PIXEL_COUNT",
2808c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT,
2818c2ecf20Sopenharmony_ci				&perf_reg_read
2828c2ecf20Sopenharmony_ci			},
2838c2ecf20Sopenharmony_ci			{
2848c2ecf20Sopenharmony_ci				"TOTAL_QUAD_COUNT",
2858c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT,
2868c2ecf20Sopenharmony_ci				&perf_reg_read
2878c2ecf20Sopenharmony_ci			},
2888c2ecf20Sopenharmony_ci			{
2898c2ecf20Sopenharmony_ci				"VALID_QUAD_COUNT_AFTER_EARLY_Z",
2908c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
2918c2ecf20Sopenharmony_ci				&perf_reg_read
2928c2ecf20Sopenharmony_ci			},
2938c2ecf20Sopenharmony_ci			{
2948c2ecf20Sopenharmony_ci				"TOTAL_PRIMITIVE_COUNT",
2958c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT,
2968c2ecf20Sopenharmony_ci				&perf_reg_read
2978c2ecf20Sopenharmony_ci			},
2988c2ecf20Sopenharmony_ci			{
2998c2ecf20Sopenharmony_ci				"PIPE_CACHE_MISS_COUNTER",
3008c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER,
3018c2ecf20Sopenharmony_ci				&perf_reg_read
3028c2ecf20Sopenharmony_ci			},
3038c2ecf20Sopenharmony_ci			{
3048c2ecf20Sopenharmony_ci				"PREFETCH_CACHE_MISS_COUNTER",
3058c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER,
3068c2ecf20Sopenharmony_ci				&perf_reg_read
3078c2ecf20Sopenharmony_ci			},
3088c2ecf20Sopenharmony_ci			{
3098c2ecf20Sopenharmony_ci				"CULLED_QUAD_COUNT",
3108c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT,
3118c2ecf20Sopenharmony_ci				&perf_reg_read
3128c2ecf20Sopenharmony_ci			}
3138c2ecf20Sopenharmony_ci		}
3148c2ecf20Sopenharmony_ci	},
3158c2ecf20Sopenharmony_ci	{
3168c2ecf20Sopenharmony_ci		.name = "TX",
3178c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_TX_READ,
3188c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG1,
3198c2ecf20Sopenharmony_ci		.nr_signals = 9,
3208c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
3218c2ecf20Sopenharmony_ci			{
3228c2ecf20Sopenharmony_ci				"TOTAL_BILINEAR_REQUESTS",
3238c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS,
3248c2ecf20Sopenharmony_ci				&perf_reg_read
3258c2ecf20Sopenharmony_ci			},
3268c2ecf20Sopenharmony_ci			{
3278c2ecf20Sopenharmony_ci				"TOTAL_TRILINEAR_REQUESTS",
3288c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS,
3298c2ecf20Sopenharmony_ci				&perf_reg_read
3308c2ecf20Sopenharmony_ci			},
3318c2ecf20Sopenharmony_ci			{
3328c2ecf20Sopenharmony_ci				"TOTAL_DISCARDED_TEXTURE_REQUESTS",
3338c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
3348c2ecf20Sopenharmony_ci				&perf_reg_read
3358c2ecf20Sopenharmony_ci			},
3368c2ecf20Sopenharmony_ci			{
3378c2ecf20Sopenharmony_ci				"TOTAL_TEXTURE_REQUESTS",
3388c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS,
3398c2ecf20Sopenharmony_ci				&perf_reg_read
3408c2ecf20Sopenharmony_ci			},
3418c2ecf20Sopenharmony_ci			{
3428c2ecf20Sopenharmony_ci				"MEM_READ_COUNT",
3438c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT,
3448c2ecf20Sopenharmony_ci				&perf_reg_read
3458c2ecf20Sopenharmony_ci			},
3468c2ecf20Sopenharmony_ci			{
3478c2ecf20Sopenharmony_ci				"MEM_READ_IN_8B_COUNT",
3488c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT,
3498c2ecf20Sopenharmony_ci				&perf_reg_read
3508c2ecf20Sopenharmony_ci			},
3518c2ecf20Sopenharmony_ci			{
3528c2ecf20Sopenharmony_ci				"CACHE_MISS_COUNT",
3538c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT,
3548c2ecf20Sopenharmony_ci				&perf_reg_read
3558c2ecf20Sopenharmony_ci			},
3568c2ecf20Sopenharmony_ci			{
3578c2ecf20Sopenharmony_ci				"CACHE_HIT_TEXEL_COUNT",
3588c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT,
3598c2ecf20Sopenharmony_ci				&perf_reg_read
3608c2ecf20Sopenharmony_ci			},
3618c2ecf20Sopenharmony_ci			{
3628c2ecf20Sopenharmony_ci				"CACHE_MISS_TEXEL_COUNT",
3638c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT,
3648c2ecf20Sopenharmony_ci				&perf_reg_read
3658c2ecf20Sopenharmony_ci			}
3668c2ecf20Sopenharmony_ci		}
3678c2ecf20Sopenharmony_ci	},
3688c2ecf20Sopenharmony_ci	{
3698c2ecf20Sopenharmony_ci		.name = "MC",
3708c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_MC_READ,
3718c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG2,
3728c2ecf20Sopenharmony_ci		.nr_signals = 3,
3738c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
3748c2ecf20Sopenharmony_ci			{
3758c2ecf20Sopenharmony_ci				"TOTAL_READ_REQ_8B_FROM_PIPELINE",
3768c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
3778c2ecf20Sopenharmony_ci				&perf_reg_read
3788c2ecf20Sopenharmony_ci			},
3798c2ecf20Sopenharmony_ci			{
3808c2ecf20Sopenharmony_ci				"TOTAL_READ_REQ_8B_FROM_IP",
3818c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP,
3828c2ecf20Sopenharmony_ci				&perf_reg_read
3838c2ecf20Sopenharmony_ci			},
3848c2ecf20Sopenharmony_ci			{
3858c2ecf20Sopenharmony_ci				"TOTAL_WRITE_REQ_8B_FROM_PIPELINE",
3868c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
3878c2ecf20Sopenharmony_ci				&perf_reg_read
3888c2ecf20Sopenharmony_ci			}
3898c2ecf20Sopenharmony_ci		}
3908c2ecf20Sopenharmony_ci	}
3918c2ecf20Sopenharmony_ci};
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_cistatic const struct etnaviv_pm_domain doms_2d[] = {
3948c2ecf20Sopenharmony_ci	{
3958c2ecf20Sopenharmony_ci		.name = "PE",
3968c2ecf20Sopenharmony_ci		.profile_read = VIVS_MC_PROFILE_PE_READ,
3978c2ecf20Sopenharmony_ci		.profile_config = VIVS_MC_PROFILE_CONFIG0,
3988c2ecf20Sopenharmony_ci		.nr_signals = 1,
3998c2ecf20Sopenharmony_ci		.signal = (const struct etnaviv_pm_signal[]) {
4008c2ecf20Sopenharmony_ci			{
4018c2ecf20Sopenharmony_ci				"PIXELS_RENDERED_2D",
4028c2ecf20Sopenharmony_ci				VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D,
4038c2ecf20Sopenharmony_ci				&pipe_reg_read
4048c2ecf20Sopenharmony_ci			}
4058c2ecf20Sopenharmony_ci		}
4068c2ecf20Sopenharmony_ci	}
4078c2ecf20Sopenharmony_ci};
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_cistatic const struct etnaviv_pm_domain doms_vg[] = {
4108c2ecf20Sopenharmony_ci};
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_cistatic const struct etnaviv_pm_domain_meta doms_meta[] = {
4138c2ecf20Sopenharmony_ci	{
4148c2ecf20Sopenharmony_ci		.feature = chipFeatures_PIPE_3D,
4158c2ecf20Sopenharmony_ci		.nr_domains = ARRAY_SIZE(doms_3d),
4168c2ecf20Sopenharmony_ci		.domains = &doms_3d[0]
4178c2ecf20Sopenharmony_ci	},
4188c2ecf20Sopenharmony_ci	{
4198c2ecf20Sopenharmony_ci		.feature = chipFeatures_PIPE_2D,
4208c2ecf20Sopenharmony_ci		.nr_domains = ARRAY_SIZE(doms_2d),
4218c2ecf20Sopenharmony_ci		.domains = &doms_2d[0]
4228c2ecf20Sopenharmony_ci	},
4238c2ecf20Sopenharmony_ci	{
4248c2ecf20Sopenharmony_ci		.feature = chipFeatures_PIPE_VG,
4258c2ecf20Sopenharmony_ci		.nr_domains = ARRAY_SIZE(doms_vg),
4268c2ecf20Sopenharmony_ci		.domains = &doms_vg[0]
4278c2ecf20Sopenharmony_ci	}
4288c2ecf20Sopenharmony_ci};
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_cistatic unsigned int num_pm_domains(const struct etnaviv_gpu *gpu)
4318c2ecf20Sopenharmony_ci{
4328c2ecf20Sopenharmony_ci	unsigned int num = 0, i;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
4358c2ecf20Sopenharmony_ci		const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci		if (gpu->identity.features & meta->feature)
4388c2ecf20Sopenharmony_ci			num += meta->nr_domains;
4398c2ecf20Sopenharmony_ci	}
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci	return num;
4428c2ecf20Sopenharmony_ci}
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_cistatic const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu,
4458c2ecf20Sopenharmony_ci	unsigned int index)
4468c2ecf20Sopenharmony_ci{
4478c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *domain = NULL;
4488c2ecf20Sopenharmony_ci	unsigned int offset = 0, i;
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
4518c2ecf20Sopenharmony_ci		const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci		if (!(gpu->identity.features & meta->feature))
4548c2ecf20Sopenharmony_ci			continue;
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci		if (index - offset >= meta->nr_domains) {
4578c2ecf20Sopenharmony_ci			offset += meta->nr_domains;
4588c2ecf20Sopenharmony_ci			continue;
4598c2ecf20Sopenharmony_ci		}
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci		domain = meta->domains + (index - offset);
4628c2ecf20Sopenharmony_ci	}
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci	return domain;
4658c2ecf20Sopenharmony_ci}
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ciint etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
4688c2ecf20Sopenharmony_ci	struct drm_etnaviv_pm_domain *domain)
4698c2ecf20Sopenharmony_ci{
4708c2ecf20Sopenharmony_ci	const unsigned int nr_domains = num_pm_domains(gpu);
4718c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *dom;
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	if (domain->iter >= nr_domains)
4748c2ecf20Sopenharmony_ci		return -EINVAL;
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	dom = pm_domain(gpu, domain->iter);
4778c2ecf20Sopenharmony_ci	if (!dom)
4788c2ecf20Sopenharmony_ci		return -EINVAL;
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	domain->id = domain->iter;
4818c2ecf20Sopenharmony_ci	domain->nr_signals = dom->nr_signals;
4828c2ecf20Sopenharmony_ci	strncpy(domain->name, dom->name, sizeof(domain->name));
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	domain->iter++;
4858c2ecf20Sopenharmony_ci	if (domain->iter == nr_domains)
4868c2ecf20Sopenharmony_ci		domain->iter = 0xff;
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	return 0;
4898c2ecf20Sopenharmony_ci}
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ciint etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
4928c2ecf20Sopenharmony_ci	struct drm_etnaviv_pm_signal *signal)
4938c2ecf20Sopenharmony_ci{
4948c2ecf20Sopenharmony_ci	const unsigned int nr_domains = num_pm_domains(gpu);
4958c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *dom;
4968c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *sig;
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	if (signal->domain >= nr_domains)
4998c2ecf20Sopenharmony_ci		return -EINVAL;
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	dom = pm_domain(gpu, signal->domain);
5028c2ecf20Sopenharmony_ci	if (!dom)
5038c2ecf20Sopenharmony_ci		return -EINVAL;
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	if (signal->iter >= dom->nr_signals)
5068c2ecf20Sopenharmony_ci		return -EINVAL;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	sig = &dom->signal[signal->iter];
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci	signal->id = signal->iter;
5118c2ecf20Sopenharmony_ci	strncpy(signal->name, sig->name, sizeof(signal->name));
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	signal->iter++;
5148c2ecf20Sopenharmony_ci	if (signal->iter == dom->nr_signals)
5158c2ecf20Sopenharmony_ci		signal->iter = 0xffff;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	return 0;
5188c2ecf20Sopenharmony_ci}
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ciint etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,
5218c2ecf20Sopenharmony_ci	u32 exec_state)
5228c2ecf20Sopenharmony_ci{
5238c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
5248c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *dom;
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	if (r->domain >= meta->nr_domains)
5278c2ecf20Sopenharmony_ci		return -EINVAL;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	dom = meta->domains + r->domain;
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci	if (r->signal >= dom->nr_signals)
5328c2ecf20Sopenharmony_ci		return -EINVAL;
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci	return 0;
5358c2ecf20Sopenharmony_ci}
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_civoid etnaviv_perfmon_process(struct etnaviv_gpu *gpu,
5388c2ecf20Sopenharmony_ci	const struct etnaviv_perfmon_request *pmr, u32 exec_state)
5398c2ecf20Sopenharmony_ci{
5408c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
5418c2ecf20Sopenharmony_ci	const struct etnaviv_pm_domain *dom;
5428c2ecf20Sopenharmony_ci	const struct etnaviv_pm_signal *sig;
5438c2ecf20Sopenharmony_ci	u32 *bo = pmr->bo_vma;
5448c2ecf20Sopenharmony_ci	u32 val;
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	dom = meta->domains + pmr->domain;
5478c2ecf20Sopenharmony_ci	sig = &dom->signal[pmr->signal];
5488c2ecf20Sopenharmony_ci	val = sig->sample(gpu, dom, sig);
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci	*(bo + pmr->offset) = val;
5518c2ecf20Sopenharmony_ci}
552