17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2021 Google, Inc. 37ec681f3Smrg * 47ec681f3Smrg * SPDX-License-Identifier: MIT 57ec681f3Smrg */ 67ec681f3Smrg 77ec681f3Smrg#pragma once 87ec681f3Smrg 97ec681f3Smrg#include "pps/pps_driver.h" 107ec681f3Smrg 117ec681f3Smrg#include "common/freedreno_dev_info.h" 127ec681f3Smrg#include "drm/freedreno_drmif.h" 137ec681f3Smrg#include "drm/freedreno_ringbuffer.h" 147ec681f3Smrg#include "perfcntrs/freedreno_dt.h" 157ec681f3Smrg#include "perfcntrs/freedreno_perfcntr.h" 167ec681f3Smrg 177ec681f3Smrgnamespace pps 187ec681f3Smrg{ 197ec681f3Smrg 207ec681f3Smrgclass FreedrenoDriver : public Driver 217ec681f3Smrg{ 227ec681f3Smrgpublic: 237ec681f3Smrg uint64_t get_min_sampling_period_ns() override; 247ec681f3Smrg bool init_perfcnt() override; 257ec681f3Smrg void enable_counter(uint32_t counter_id) override; 267ec681f3Smrg void enable_all_counters() override; 277ec681f3Smrg void enable_perfcnt(uint64_t sampling_period_ns) override; 287ec681f3Smrg void disable_perfcnt() override; 297ec681f3Smrg bool dump_perfcnt() override; 307ec681f3Smrg uint64_t next() override; 317ec681f3Smrg 327ec681f3Smrgprivate: 337ec681f3Smrg struct fd_device *dev; 347ec681f3Smrg struct fd_pipe *pipe; 357ec681f3Smrg const struct fd_dev_id *dev_id; 367ec681f3Smrg uint32_t max_freq; 377ec681f3Smrg uint32_t next_counter_id; 387ec681f3Smrg uint32_t next_countable_id; 397ec681f3Smrg uint64_t last_dump_ts = 0; 407ec681f3Smrg uint64_t last_capture_ts; 417ec681f3Smrg 427ec681f3Smrg bool has_suspend_count; 437ec681f3Smrg uint32_t suspend_count; 447ec681f3Smrg 457ec681f3Smrg const struct fd_dev_info *info; 467ec681f3Smrg 477ec681f3Smrg /** 487ec681f3Smrg * The memory mapped i/o space for counter readback: 497ec681f3Smrg */ 507ec681f3Smrg void *io; 517ec681f3Smrg 527ec681f3Smrg const struct fd_perfcntr_group *perfcntrs; 537ec681f3Smrg unsigned num_perfcntrs; 547ec681f3Smrg 557ec681f3Smrg /** 567ec681f3Smrg * The number of counters assigned per perfcntr group, the index 577ec681f3Smrg * into this matches the index into perfcntrs 587ec681f3Smrg */ 597ec681f3Smrg std::vector<int> assigned_counters; 607ec681f3Smrg 617ec681f3Smrg /* 627ec681f3Smrg * Values that can be used by derived counters evaluation 637ec681f3Smrg */ 647ec681f3Smrg float time; /* time since last sample in fraction of second */ 657ec681f3Smrg// uint32_t cycles; /* the number of clock cycles since last sample */ 667ec681f3Smrg 677ec681f3Smrg void setup_a6xx_counters(); 687ec681f3Smrg 697ec681f3Smrg void configure_counters(bool reset, bool wait); 707ec681f3Smrg void collect_countables(); 717ec681f3Smrg 727ec681f3Smrg /** 737ec681f3Smrg * Split out countable mutable state from the class so that copy- 747ec681f3Smrg * constructor does something sane when lambda derive function 757ec681f3Smrg * tries to get the countable value. 767ec681f3Smrg */ 777ec681f3Smrg struct CountableState { 787ec681f3Smrg uint64_t last_value, value; 797ec681f3Smrg const struct fd_perfcntr_countable *countable; 807ec681f3Smrg const struct fd_perfcntr_counter *counter; 817ec681f3Smrg }; 827ec681f3Smrg 837ec681f3Smrg std::vector<struct CountableState> state; 847ec681f3Smrg 857ec681f3Smrg /** 867ec681f3Smrg * Performance counters on adreno consist of sets of counters in various 877ec681f3Smrg * blocks of the GPU, where each counter can be can be muxed to collect 887ec681f3Smrg * one of a set of countables. 897ec681f3Smrg * 907ec681f3Smrg * But the countables tend to be too low level to be directly useful to 917ec681f3Smrg * visualize. Instead various combinations of countables are combined 927ec681f3Smrg * with various formulas to derive the high level "Counter" value exposed 937ec681f3Smrg * via gfx-pps. 947ec681f3Smrg * 957ec681f3Smrg * This class serves to decouple the logic of those formulas from the 967ec681f3Smrg * details of collecting countable values. 977ec681f3Smrg */ 987ec681f3Smrg class Countable { 997ec681f3Smrg public: 1007ec681f3Smrg Countable(FreedrenoDriver *d, std::string name); 1017ec681f3Smrg 1027ec681f3Smrg operator int64_t() const { return get_value(); }; 1037ec681f3Smrg 1047ec681f3Smrg void configure(struct fd_ringbuffer *ring, bool reset); 1057ec681f3Smrg void collect(); 1067ec681f3Smrg void resolve(); 1077ec681f3Smrg 1087ec681f3Smrg private: 1097ec681f3Smrg 1107ec681f3Smrg uint64_t get_value() const; 1117ec681f3Smrg 1127ec681f3Smrg uint32_t id; 1137ec681f3Smrg FreedrenoDriver *d; 1147ec681f3Smrg std::string name; 1157ec681f3Smrg }; 1167ec681f3Smrg 1177ec681f3Smrg Countable countable(std::string name); 1187ec681f3Smrg 1197ec681f3Smrg std::vector<Countable> countables; 1207ec681f3Smrg 1217ec681f3Smrg /** 1227ec681f3Smrg * A derived "Counter" (from pps's perspective) 1237ec681f3Smrg */ 1247ec681f3Smrg class DerivedCounter : public Counter { 1257ec681f3Smrg public: 1267ec681f3Smrg DerivedCounter(FreedrenoDriver *d, std::string name, Counter::Units units, 1277ec681f3Smrg std::function<int64_t()> derive); 1287ec681f3Smrg }; 1297ec681f3Smrg 1307ec681f3Smrg DerivedCounter counter(std::string name, Counter::Units units, 1317ec681f3Smrg std::function<int64_t()> derive); 1327ec681f3Smrg}; 1337ec681f3Smrg 1347ec681f3Smrg} // namespace pps 135