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