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 
17 namespace pps
18 {
19 
20 class FreedrenoDriver : public Driver
21 {
22 public:
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 
34 private:
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 
int64_t()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