1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Google, Inc.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT
5bf215546Sopenharmony_ci */
6bf215546Sopenharmony_ci
7bf215546Sopenharmony_ci#pragma once
8bf215546Sopenharmony_ci
9bf215546Sopenharmony_ci#include "pps/pps_driver.h"
10bf215546Sopenharmony_ci
11bf215546Sopenharmony_ci#include "common/freedreno_dev_info.h"
12bf215546Sopenharmony_ci#include "drm/freedreno_drmif.h"
13bf215546Sopenharmony_ci#include "drm/freedreno_ringbuffer.h"
14bf215546Sopenharmony_ci#include "perfcntrs/freedreno_dt.h"
15bf215546Sopenharmony_ci#include "perfcntrs/freedreno_perfcntr.h"
16bf215546Sopenharmony_ci
17bf215546Sopenharmony_cinamespace pps
18bf215546Sopenharmony_ci{
19bf215546Sopenharmony_ci
20bf215546Sopenharmony_ciclass FreedrenoDriver : public Driver
21bf215546Sopenharmony_ci{
22bf215546Sopenharmony_cipublic:
23bf215546Sopenharmony_ci   uint64_t get_min_sampling_period_ns() override;
24bf215546Sopenharmony_ci   bool init_perfcnt() override;
25bf215546Sopenharmony_ci   void enable_counter(uint32_t counter_id) override;
26bf215546Sopenharmony_ci   void enable_all_counters() override;
27bf215546Sopenharmony_ci   void enable_perfcnt(uint64_t sampling_period_ns) override;
28bf215546Sopenharmony_ci   void disable_perfcnt() override;
29bf215546Sopenharmony_ci   bool dump_perfcnt() override;
30bf215546Sopenharmony_ci   uint64_t next() override;
31bf215546Sopenharmony_ci   uint32_t gpu_clock_id() const override;
32bf215546Sopenharmony_ci   uint64_t gpu_timestamp() const override;
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ciprivate:
35bf215546Sopenharmony_ci   struct fd_device *dev;
36bf215546Sopenharmony_ci   struct fd_pipe *pipe;
37bf215546Sopenharmony_ci   const struct fd_dev_id *dev_id;
38bf215546Sopenharmony_ci   uint32_t max_freq;
39bf215546Sopenharmony_ci   uint32_t next_counter_id;
40bf215546Sopenharmony_ci   uint32_t next_countable_id;
41bf215546Sopenharmony_ci   uint64_t last_dump_ts = 0;
42bf215546Sopenharmony_ci   uint64_t last_capture_ts;
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci   bool has_suspend_count;
45bf215546Sopenharmony_ci   uint32_t suspend_count;
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci   const struct fd_dev_info *info;
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   /**
50bf215546Sopenharmony_ci    * The memory mapped i/o space for counter readback:
51bf215546Sopenharmony_ci    */
52bf215546Sopenharmony_ci   void *io;
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci   const struct fd_perfcntr_group *perfcntrs;
55bf215546Sopenharmony_ci   unsigned num_perfcntrs;
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci   /**
58bf215546Sopenharmony_ci    * The number of counters assigned per perfcntr group, the index
59bf215546Sopenharmony_ci    * into this matches the index into perfcntrs
60bf215546Sopenharmony_ci    */
61bf215546Sopenharmony_ci   std::vector<int> assigned_counters;
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   /*
64bf215546Sopenharmony_ci    * Values that can be used by derived counters evaluation
65bf215546Sopenharmony_ci    */
66bf215546Sopenharmony_ci   float time;  /* time since last sample in fraction of second */
67bf215546Sopenharmony_ci//   uint32_t cycles;  /* the number of clock cycles since last sample */
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci   void setup_a6xx_counters();
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   void configure_counters(bool reset, bool wait);
72bf215546Sopenharmony_ci   void collect_countables();
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci   /**
75bf215546Sopenharmony_ci    * Split out countable mutable state from the class so that copy-
76bf215546Sopenharmony_ci    * constructor does something sane when lambda derive function
77bf215546Sopenharmony_ci    * tries to get the countable value.
78bf215546Sopenharmony_ci    */
79bf215546Sopenharmony_ci   struct CountableState {
80bf215546Sopenharmony_ci      uint64_t last_value, value;
81bf215546Sopenharmony_ci      const struct fd_perfcntr_countable *countable;
82bf215546Sopenharmony_ci      const struct fd_perfcntr_counter   *counter;
83bf215546Sopenharmony_ci   };
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   std::vector<struct CountableState> state;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   /**
88bf215546Sopenharmony_ci    * Performance counters on adreno consist of sets of counters in various
89bf215546Sopenharmony_ci    * blocks of the GPU, where each counter can be can be muxed to collect
90bf215546Sopenharmony_ci    * one of a set of countables.
91bf215546Sopenharmony_ci    *
92bf215546Sopenharmony_ci    * But the countables tend to be too low level to be directly useful to
93bf215546Sopenharmony_ci    * visualize.  Instead various combinations of countables are combined
94bf215546Sopenharmony_ci    * with various formulas to derive the high level "Counter" value exposed
95bf215546Sopenharmony_ci    * via gfx-pps.
96bf215546Sopenharmony_ci    *
97bf215546Sopenharmony_ci    * This class serves to decouple the logic of those formulas from the
98bf215546Sopenharmony_ci    * details of collecting countable values.
99bf215546Sopenharmony_ci    */
100bf215546Sopenharmony_ci   class Countable {
101bf215546Sopenharmony_ci   public:
102bf215546Sopenharmony_ci      Countable(FreedrenoDriver *d, std::string name);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci      operator int64_t() const { return get_value(); };
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci      void configure(struct fd_ringbuffer *ring, bool reset);
107bf215546Sopenharmony_ci      void collect();
108bf215546Sopenharmony_ci      void resolve();
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   private:
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci      uint64_t get_value() const;
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci      uint32_t id;
115bf215546Sopenharmony_ci      FreedrenoDriver *d;
116bf215546Sopenharmony_ci      std::string name;
117bf215546Sopenharmony_ci   };
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci   Countable countable(std::string name);
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci   std::vector<Countable> countables;
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   /**
124bf215546Sopenharmony_ci    * A derived "Counter" (from pps's perspective)
125bf215546Sopenharmony_ci    */
126bf215546Sopenharmony_ci   class DerivedCounter : public Counter {
127bf215546Sopenharmony_ci   public:
128bf215546Sopenharmony_ci      DerivedCounter(FreedrenoDriver *d, std::string name, Counter::Units units,
129bf215546Sopenharmony_ci                     std::function<int64_t()> derive);
130bf215546Sopenharmony_ci   };
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci   DerivedCounter counter(std::string name, Counter::Units units,
133bf215546Sopenharmony_ci                          std::function<int64_t()> derive);
134bf215546Sopenharmony_ci};
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ci} // namespace pps
137