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