brintos

brintos / linux-shallow public Read only

0
0
Text · 13.0 KiB · dc9dea6 Raw
584 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2017 Etnaviv Project4 * Copyright (C) 2017 Zodiac Inflight Innovations5 */6 7#include "common.xml.h"8#include "etnaviv_gpu.h"9#include "etnaviv_perfmon.h"10#include "state_hi.xml.h"11 12struct etnaviv_pm_domain;13 14struct etnaviv_pm_signal {15	char name[64];16	u32 data;17 18	u32 (*sample)(struct etnaviv_gpu *gpu,19		      const struct etnaviv_pm_domain *domain,20		      const struct etnaviv_pm_signal *signal);21};22 23struct etnaviv_pm_domain {24	char name[64];25 26	/* profile register */27	u32 profile_read;28	u32 profile_config;29 30	u8 nr_signals;31	const struct etnaviv_pm_signal *signal;32};33 34struct etnaviv_pm_domain_meta {35	unsigned int feature;36	const struct etnaviv_pm_domain *domains;37	u32 nr_domains;38};39 40static u32 perf_reg_read(struct etnaviv_gpu *gpu,41	const struct etnaviv_pm_domain *domain,42	const struct etnaviv_pm_signal *signal)43{44	gpu_write(gpu, domain->profile_config, signal->data);45 46	return gpu_read(gpu, domain->profile_read);47}48 49static inline void pipe_select(struct etnaviv_gpu *gpu, u32 clock, unsigned pipe)50{51	clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);52	clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(pipe);53 54	gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);55}56 57static u32 pipe_perf_reg_read(struct etnaviv_gpu *gpu,58	const struct etnaviv_pm_domain *domain,59	const struct etnaviv_pm_signal *signal)60{61	u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);62	u32 value = 0;63	unsigned i;64 65	for (i = 0; i < gpu->identity.pixel_pipes; i++) {66		pipe_select(gpu, clock, i);67		value += perf_reg_read(gpu, domain, signal);68	}69 70	/* switch back to pixel pipe 0 to prevent GPU hang */71	pipe_select(gpu, clock, 0);72 73	return value;74}75 76static u32 pipe_reg_read(struct etnaviv_gpu *gpu,77	const struct etnaviv_pm_domain *domain,78	const struct etnaviv_pm_signal *signal)79{80	u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);81	u32 value = 0;82	unsigned i;83 84	for (i = 0; i < gpu->identity.pixel_pipes; i++) {85		pipe_select(gpu, clock, i);86		value += gpu_read(gpu, signal->data);87	}88 89	/* switch back to pixel pipe 0 to prevent GPU hang */90	pipe_select(gpu, clock, 0);91 92	return value;93}94 95static u32 hi_total_cycle_read(struct etnaviv_gpu *gpu,96	const struct etnaviv_pm_domain *domain,97	const struct etnaviv_pm_signal *signal)98{99	u32 reg = VIVS_HI_PROFILE_TOTAL_CYCLES;100 101	if (gpu->identity.model == chipModel_GC880 ||102		gpu->identity.model == chipModel_GC2000 ||103		gpu->identity.model == chipModel_GC2100)104		reg = VIVS_MC_PROFILE_CYCLE_COUNTER;105 106	return gpu_read(gpu, reg);107}108 109static u32 hi_total_idle_cycle_read(struct etnaviv_gpu *gpu,110	const struct etnaviv_pm_domain *domain,111	const struct etnaviv_pm_signal *signal)112{113	u32 reg = VIVS_HI_PROFILE_IDLE_CYCLES;114 115	if (gpu->identity.model == chipModel_GC880 ||116		gpu->identity.model == chipModel_GC2000 ||117		gpu->identity.model == chipModel_GC2100)118		reg = VIVS_HI_PROFILE_TOTAL_CYCLES;119 120	return gpu_read(gpu, reg);121}122 123static const struct etnaviv_pm_domain doms_3d[] = {124	{125		.name = "HI",126		.profile_read = VIVS_MC_PROFILE_HI_READ,127		.profile_config = VIVS_MC_PROFILE_CONFIG2,128		.nr_signals = 7,129		.signal = (const struct etnaviv_pm_signal[]) {130			{131				"TOTAL_READ_BYTES8",132				VIVS_HI_PROFILE_READ_BYTES8,133				&pipe_reg_read,134			},135			{136				"TOTAL_WRITE_BYTES8",137				VIVS_HI_PROFILE_WRITE_BYTES8,138				&pipe_reg_read,139			},140			{141				"TOTAL_CYCLES",142				0,143				&hi_total_cycle_read144			},145			{146				"IDLE_CYCLES",147				0,148				&hi_total_idle_cycle_read149			},150			{151				"AXI_CYCLES_READ_REQUEST_STALLED",152				VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED,153				&perf_reg_read154			},155			{156				"AXI_CYCLES_WRITE_REQUEST_STALLED",157				VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,158				&perf_reg_read159			},160			{161				"AXI_CYCLES_WRITE_DATA_STALLED",162				VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED,163				&perf_reg_read164			}165		}166	},167	{168		.name = "PE",169		.profile_read = VIVS_MC_PROFILE_PE_READ,170		.profile_config = VIVS_MC_PROFILE_CONFIG0,171		.nr_signals = 4,172		.signal = (const struct etnaviv_pm_signal[]) {173			{174				"PIXEL_COUNT_KILLED_BY_COLOR_PIPE",175				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,176				&pipe_perf_reg_read177			},178			{179				"PIXEL_COUNT_KILLED_BY_DEPTH_PIPE",180				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,181				&pipe_perf_reg_read182			},183			{184				"PIXEL_COUNT_DRAWN_BY_COLOR_PIPE",185				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,186				&pipe_perf_reg_read187			},188			{189				"PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE",190				VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,191				&pipe_perf_reg_read192			}193		}194	},195	{196		.name = "SH",197		.profile_read = VIVS_MC_PROFILE_SH_READ,198		.profile_config = VIVS_MC_PROFILE_CONFIG0,199		.nr_signals = 9,200		.signal = (const struct etnaviv_pm_signal[]) {201			{202				"SHADER_CYCLES",203				VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES,204				&perf_reg_read205			},206			{207				"PS_INST_COUNTER",208				VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER,209				&perf_reg_read210			},211			{212				"RENDERED_PIXEL_COUNTER",213				VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER,214				&perf_reg_read215			},216			{217				"VS_INST_COUNTER",218				VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER,219				&pipe_perf_reg_read220			},221			{222				"RENDERED_VERTICE_COUNTER",223				VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER,224				&pipe_perf_reg_read225			},226			{227				"VTX_BRANCH_INST_COUNTER",228				VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER,229				&pipe_perf_reg_read230			},231			{232				"VTX_TEXLD_INST_COUNTER",233				VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER,234				&pipe_perf_reg_read235			},236			{237				"PXL_BRANCH_INST_COUNTER",238				VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER,239				&pipe_perf_reg_read240			},241			{242				"PXL_TEXLD_INST_COUNTER",243				VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER,244				&pipe_perf_reg_read245			}246		}247	},248	{249		.name = "PA",250		.profile_read = VIVS_MC_PROFILE_PA_READ,251		.profile_config = VIVS_MC_PROFILE_CONFIG1,252		.nr_signals = 6,253		.signal = (const struct etnaviv_pm_signal[]) {254			{255				"INPUT_VTX_COUNTER",256				VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER,257				&perf_reg_read258			},259			{260				"INPUT_PRIM_COUNTER",261				VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER,262				&perf_reg_read263			},264			{265				"OUTPUT_PRIM_COUNTER",266				VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER,267				&perf_reg_read268			},269			{270				"DEPTH_CLIPPED_COUNTER",271				VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER,272				&pipe_perf_reg_read273			},274			{275				"TRIVIAL_REJECTED_COUNTER",276				VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER,277				&pipe_perf_reg_read278			},279			{280				"CULLED_COUNTER",281				VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER,282				&pipe_perf_reg_read283			}284		}285	},286	{287		.name = "SE",288		.profile_read = VIVS_MC_PROFILE_SE_READ,289		.profile_config = VIVS_MC_PROFILE_CONFIG1,290		.nr_signals = 2,291		.signal = (const struct etnaviv_pm_signal[]) {292			{293				"CULLED_TRIANGLE_COUNT",294				VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT,295				&perf_reg_read296			},297			{298				"CULLED_LINES_COUNT",299				VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT,300				&perf_reg_read301			}302		}303	},304	{305		.name = "RA",306		.profile_read = VIVS_MC_PROFILE_RA_READ,307		.profile_config = VIVS_MC_PROFILE_CONFIG1,308		.nr_signals = 7,309		.signal = (const struct etnaviv_pm_signal[]) {310			{311				"VALID_PIXEL_COUNT",312				VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT,313				&perf_reg_read314			},315			{316				"TOTAL_QUAD_COUNT",317				VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT,318				&perf_reg_read319			},320			{321				"VALID_QUAD_COUNT_AFTER_EARLY_Z",322				VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,323				&perf_reg_read324			},325			{326				"TOTAL_PRIMITIVE_COUNT",327				VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT,328				&perf_reg_read329			},330			{331				"PIPE_CACHE_MISS_COUNTER",332				VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER,333				&perf_reg_read334			},335			{336				"PREFETCH_CACHE_MISS_COUNTER",337				VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER,338				&perf_reg_read339			},340			{341				"CULLED_QUAD_COUNT",342				VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT,343				&perf_reg_read344			}345		}346	},347	{348		.name = "TX",349		.profile_read = VIVS_MC_PROFILE_TX_READ,350		.profile_config = VIVS_MC_PROFILE_CONFIG1,351		.nr_signals = 9,352		.signal = (const struct etnaviv_pm_signal[]) {353			{354				"TOTAL_BILINEAR_REQUESTS",355				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS,356				&perf_reg_read357			},358			{359				"TOTAL_TRILINEAR_REQUESTS",360				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS,361				&perf_reg_read362			},363			{364				"TOTAL_DISCARDED_TEXTURE_REQUESTS",365				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,366				&perf_reg_read367			},368			{369				"TOTAL_TEXTURE_REQUESTS",370				VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS,371				&perf_reg_read372			},373			{374				"MEM_READ_COUNT",375				VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT,376				&perf_reg_read377			},378			{379				"MEM_READ_IN_8B_COUNT",380				VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT,381				&perf_reg_read382			},383			{384				"CACHE_MISS_COUNT",385				VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT,386				&perf_reg_read387			},388			{389				"CACHE_HIT_TEXEL_COUNT",390				VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT,391				&perf_reg_read392			},393			{394				"CACHE_MISS_TEXEL_COUNT",395				VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT,396				&perf_reg_read397			}398		}399	},400	{401		.name = "MC",402		.profile_read = VIVS_MC_PROFILE_MC_READ,403		.profile_config = VIVS_MC_PROFILE_CONFIG2,404		.nr_signals = 3,405		.signal = (const struct etnaviv_pm_signal[]) {406			{407				"TOTAL_READ_REQ_8B_FROM_PIPELINE",408				VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,409				&perf_reg_read410			},411			{412				"TOTAL_READ_REQ_8B_FROM_IP",413				VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP,414				&perf_reg_read415			},416			{417				"TOTAL_WRITE_REQ_8B_FROM_PIPELINE",418				VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,419				&perf_reg_read420			}421		}422	}423};424 425static const struct etnaviv_pm_domain doms_2d[] = {426	{427		.name = "PE",428		.profile_read = VIVS_MC_PROFILE_PE_READ,429		.profile_config = VIVS_MC_PROFILE_CONFIG0,430		.nr_signals = 1,431		.signal = (const struct etnaviv_pm_signal[]) {432			{433				"PIXELS_RENDERED_2D",434				VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D,435				&pipe_perf_reg_read436			}437		}438	}439};440 441static const struct etnaviv_pm_domain doms_vg[] = {442};443 444static const struct etnaviv_pm_domain_meta doms_meta[] = {445	{446		.feature = chipFeatures_PIPE_3D,447		.nr_domains = ARRAY_SIZE(doms_3d),448		.domains = &doms_3d[0]449	},450	{451		.feature = chipFeatures_PIPE_2D,452		.nr_domains = ARRAY_SIZE(doms_2d),453		.domains = &doms_2d[0]454	},455	{456		.feature = chipFeatures_PIPE_VG,457		.nr_domains = ARRAY_SIZE(doms_vg),458		.domains = &doms_vg[0]459	}460};461 462static unsigned int num_pm_domains(const struct etnaviv_gpu *gpu)463{464	unsigned int num = 0, i;465 466	for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {467		const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];468 469		if (gpu->identity.features & meta->feature)470			num += meta->nr_domains;471	}472 473	return num;474}475 476static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu,477	unsigned int index)478{479	const struct etnaviv_pm_domain *domain = NULL;480	unsigned int offset = 0, i;481 482	for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {483		const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];484 485		if (!(gpu->identity.features & meta->feature))486			continue;487 488		if (index - offset >= meta->nr_domains) {489			offset += meta->nr_domains;490			continue;491		}492 493		domain = meta->domains + (index - offset);494	}495 496	return domain;497}498 499int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,500	struct drm_etnaviv_pm_domain *domain)501{502	const unsigned int nr_domains = num_pm_domains(gpu);503	const struct etnaviv_pm_domain *dom;504 505	if (domain->iter >= nr_domains)506		return -EINVAL;507 508	dom = pm_domain(gpu, domain->iter);509	if (!dom)510		return -EINVAL;511 512	domain->id = domain->iter;513	domain->nr_signals = dom->nr_signals;514	strscpy_pad(domain->name, dom->name, sizeof(domain->name));515 516	domain->iter++;517	if (domain->iter == nr_domains)518		domain->iter = 0xff;519 520	return 0;521}522 523int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,524	struct drm_etnaviv_pm_signal *signal)525{526	const unsigned int nr_domains = num_pm_domains(gpu);527	const struct etnaviv_pm_domain *dom;528	const struct etnaviv_pm_signal *sig;529 530	if (signal->domain >= nr_domains)531		return -EINVAL;532 533	dom = pm_domain(gpu, signal->domain);534	if (!dom)535		return -EINVAL;536 537	if (signal->iter >= dom->nr_signals)538		return -EINVAL;539 540	sig = &dom->signal[signal->iter];541 542	signal->id = signal->iter;543	strscpy_pad(signal->name, sig->name, sizeof(signal->name));544 545	signal->iter++;546	if (signal->iter == dom->nr_signals)547		signal->iter = 0xffff;548 549	return 0;550}551 552int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,553	u32 exec_state)554{555	const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];556	const struct etnaviv_pm_domain *dom;557 558	if (r->domain >= meta->nr_domains)559		return -EINVAL;560 561	dom = meta->domains + r->domain;562 563	if (r->signal >= dom->nr_signals)564		return -EINVAL;565 566	return 0;567}568 569void etnaviv_perfmon_process(struct etnaviv_gpu *gpu,570	const struct etnaviv_perfmon_request *pmr, u32 exec_state)571{572	const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];573	const struct etnaviv_pm_domain *dom;574	const struct etnaviv_pm_signal *sig;575	u32 *bo = pmr->bo_vma;576	u32 val;577 578	dom = meta->domains + pmr->domain;579	sig = &dom->signal[pmr->signal];580	val = sig->sample(gpu, dom, sig);581 582	*(bo + pmr->offset) = val;583}584