// Copyright 2020 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 SRC_DEVICES_POWER_DRIVERS_AML_MESON_POWER_AML_POWER_H_
#define SRC_DEVICES_POWER_DRIVERS_AML_MESON_POWER_AML_POWER_H_

#include <lib/device-protocol/pdev.h>
#include <threads.h>

#include <array>
#include <optional>
#include <vector>

#include <ddktl/device.h>
#include <ddktl/protocol/platform/device.h>
#include <ddktl/protocol/powerimpl.h>
#include <ddktl/protocol/pwm.h>
#include <ddktl/protocol/vreg.h>
#include <soc/aml-common/aml-power.h>
#include <soc/aml-s905d2/s905d2-power.h>
#include <soc/aml-s905d3/s905d3-power.h>
#include <soc/aml-t931/t931-power.h>

namespace power {

class AmlPower;
using AmlPowerType = ddk::Device<AmlPower, ddk::Unbindable>;

class AmlPower : public AmlPowerType, public ddk::PowerImplProtocol<AmlPower, ddk::base_protocol> {
 private:
  static constexpr int kInvalidIndex = -1;

 public:

  // Constructor for Astro.
  AmlPower(zx_device_t* parent, ddk::PwmProtocolClient big_cluster_pwm,
                    const std::vector<aml_voltage_table_t> voltage_table,
                    voltage_pwm_period_ns_t pwm_period)
      : AmlPowerType(parent),
        big_cluster_pwm_(big_cluster_pwm),
        big_cluster_vreg_(std::nullopt),
        little_cluster_pwm_(std::nullopt),
        current_big_cluster_voltage_index_(kInvalidIndex),
        current_little_cluster_voltage_index_(kInvalidIndex),
        voltage_table_(voltage_table),
        pwm_period_(pwm_period),
        num_domains_(1) {}

  // Constructor for Sherlock.
  AmlPower(zx_device_t* parent, ddk::PwmProtocolClient big_cluster_pwm,
                    ddk::PwmProtocolClient little_cluster_pwm,
                    const std::vector<aml_voltage_table_t> voltage_table,
                    voltage_pwm_period_ns_t pwm_period)
      : AmlPowerType(parent),
        big_cluster_pwm_(big_cluster_pwm),
        big_cluster_vreg_(std::nullopt),
        little_cluster_pwm_(little_cluster_pwm),
        current_big_cluster_voltage_index_(kInvalidIndex),
        current_little_cluster_voltage_index_(kInvalidIndex),
        voltage_table_(voltage_table),
        pwm_period_(pwm_period),
        num_domains_(2) {}

  AmlPower(zx_device_t* parent, ddk::VregProtocolClient big_cluster_vreg,
                    ddk::PwmProtocolClient little_cluster_pwm,
                    const std::vector<aml_voltage_table_t> voltage_table,
                    voltage_pwm_period_ns_t pwm_period)
      : AmlPowerType(parent),
        big_cluster_pwm_(std::nullopt),
        big_cluster_vreg_(big_cluster_vreg),
        little_cluster_pwm_(little_cluster_pwm),
        current_big_cluster_voltage_index_(kInvalidIndex),
        current_little_cluster_voltage_index_(kInvalidIndex),
        voltage_table_(voltage_table),
        pwm_period_(pwm_period),
        num_domains_(2) {}

  AmlPower(const AmlPower&) = delete;
  AmlPower(AmlPower&&) = delete;
  AmlPower& operator=(const AmlPower&) = delete;
  AmlPower& operator=(AmlPower&&) = delete;

  virtual ~AmlPower() = default;
  static zx_status_t Create(void* ctx, zx_device_t* parent);

  // Device protocol implementation
  void DdkRelease();
  void DdkUnbind(ddk::UnbindTxn txn);

  zx_status_t PowerImplGetPowerDomainStatus(uint32_t index, power_domain_status_t* out_status);
  zx_status_t PowerImplEnablePowerDomain(uint32_t index);
  zx_status_t PowerImplDisablePowerDomain(uint32_t index);
  zx_status_t PowerImplGetSupportedVoltageRange(uint32_t index, uint32_t* min_voltage,
                                                uint32_t* max_voltage);
  zx_status_t PowerImplRequestVoltage(uint32_t index, uint32_t voltage, uint32_t* actual_voltage);
  zx_status_t PowerImplGetCurrentVoltage(uint32_t index, uint32_t* current_voltage);
  zx_status_t PowerImplWritePmicCtrlReg(uint32_t index, uint32_t addr, uint32_t value);
  zx_status_t PowerImplReadPmicCtrlReg(uint32_t index, uint32_t addr, uint32_t* value);

  static constexpr uint32_t kBigClusterDomain = 0;
  static constexpr uint32_t kLittleClusterDomain = 1;

  static_assert(kBigClusterDomain == static_cast<uint32_t>(S905d2PowerDomains::kArmCore));
  static_assert(kBigClusterDomain == static_cast<uint32_t>(S905d3PowerDomains::kArmCore));
  static_assert(kBigClusterDomain == static_cast<uint32_t>(T931PowerDomains::kArmCoreBig));
  static_assert(kLittleClusterDomain == static_cast<uint32_t>(T931PowerDomains::kArmCoreLittle));

 private:
  zx_status_t RequestVoltage(const ddk::PwmProtocolClient& pwm, uint32_t u_volts,
                             int* current_voltage_idx);
  zx_status_t SetBigClusterVoltage(uint32_t voltage, uint32_t* actual);

  std::optional<ddk::PwmProtocolClient> big_cluster_pwm_;
  std::optional<ddk::VregProtocolClient> big_cluster_vreg_;
  std::optional<ddk::PwmProtocolClient> little_cluster_pwm_;

  int current_big_cluster_voltage_index_;
  int current_little_cluster_voltage_index_;

  const std::vector<aml_voltage_table_t> voltage_table_;
  const voltage_pwm_period_ns_t pwm_period_;

  const uint32_t num_domains_;
};

}  // namespace power

#endif  // SRC_DEVICES_POWER_DRIVERS_AML_MESON_POWER_AML_POWER_H_
