// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MSD_INTEL_REGISTER_IO_H
#define MSD_INTEL_REGISTER_IO_H

#include <lib/magma/util/short_macros.h>
#include <lib/magma_service/util/register_io.h>

#include <chrono>
#include <map>

#include "device_id.h"
#include "types.h"

// Wraps the common magma::RegisterIo so we can intercept reads and writes and perform forcewake
// checks.
class MsdIntelRegisterIo {
 public:
  class Owner {
   public:
    virtual bool IsForceWakeDomainActive(ForceWakeDomain domain) = 0;
  };

  struct Range {
    uint32_t start_offset;
    uint32_t end_offset;  // inclusive
    ForceWakeDomain forcewake_domain;
  };

  MsdIntelRegisterIo(Owner* owner, std::unique_ptr<magma::PlatformMmio> mmio, uint32_t device_id);

  // Should only be used for unit testing.
  explicit MsdIntelRegisterIo(std::unique_ptr<magma::PlatformMmio> mmio)
      : MsdIntelRegisterIo(nullptr, std::move(mmio), /*device_id=*/0) {}

  magma::PlatformMmio* mmio() { return register_io_.mmio(); }

  void Write32(uint32_t val, uint32_t offset) {
    CheckForcewake(offset);
    return register_io_.Write32(val, offset);
  }

  uint32_t Read32(uint32_t offset) {
    CheckForcewake(offset);
    return register_io_.Read32(offset);
  }

  uint64_t Read64(uint32_t offset) {
    CheckForcewake(offset);
    return register_io_.Read64(offset);
  }

  // For hwreg::RegisterBase::ReadFrom.
  template <class T>
  T Read(uint32_t offset) {
    if constexpr (sizeof(T) == sizeof(uint64_t)) {
      return Read64(offset);
    } else {
      static_assert(sizeof(T) == sizeof(uint32_t));
      return Read32(offset);
    }
  }

  template <class T>
  void Write(T val, uint32_t offset) {
    static_assert(sizeof(T) == sizeof(uint32_t));
    Write32(val, offset);
  }

  void InstallHook(std::unique_ptr<magma::RegisterIo::Hook> hook) {
    register_io_.InstallHook(std::move(hook));
  }

  magma::RegisterIo::Hook* hook() { return register_io_.hook(); }

  size_t forcewake_token_count(ForceWakeDomain domain) {
    DASSERT(static_cast<size_t>(domain) < per_forcewake_.size());

    size_t count = per_forcewake_[static_cast<int>(domain)].token.use_count();

    // Don't count the one we always keep internally.
    DASSERT(count > 0);
    return count - 1;
  }

  // This token must be held while accessing registers in the given domain.
  // Note, releasing the token doesn't release the forcewake because those
  // are deferred.
  std::shared_ptr<ForceWakeDomain> GetForceWakeToken(ForceWakeDomain domain);

  std::chrono::steady_clock::duration GetForceWakeReleaseTimeout(
      ForceWakeDomain forcewake_domain, uint64_t max_release_timeout_ms,
      std::chrono::steady_clock::time_point now);

  void CheckForcewake(uint32_t register_offset);
  void CheckForcewakeForRange(const Range& range, uint32_t register_offset);

  void set_forcewake_active_check_for_test() { forcewake_active_check_for_test_ = true; }

 private:
  Owner* owner_;
  magma::RegisterIo register_io_;
  const std::map<uint32_t, Range>* forcewake_map_ = nullptr;
  bool forcewake_active_check_for_test_ = false;

  struct PerForceWake {
    std::chrono::steady_clock::time_point last_request_time =
        std::chrono::steady_clock::time_point::max();
    std::shared_ptr<ForceWakeDomain> token = std::make_shared<ForceWakeDomain>();
  };
  // Array size is the number of enum elements in ForceWakeDomain
  std::array<PerForceWake, 3> per_forcewake_;

  static const std::map<uint32_t, Range> forcewake_map_gen12_;
};

#endif  // MSD_INTEL_REGISTER_IO_H
