// Copyright 2019 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.

#include "mtk-thermal.h"

#include <lib/mock-function/mock-function.h>
#include <lib/zircon-internal/thread_annotations.h>

#include <memory>

#include <mmio-ptr/fake.h>
#include <mock-mmio-reg/mock-mmio-reg.h>
#include <soc/mt8167/mt8167-hw.h>

namespace {

constexpr size_t kThermalRegCount = MT8167_THERMAL_SIZE / sizeof(uint32_t);
constexpr size_t kPllRegCount = MT8167_AP_MIXED_SYS_SIZE / sizeof(uint32_t);
constexpr size_t kPmicWrapRegCount = MT8167_PMIC_WRAP_SIZE / sizeof(uint32_t);
constexpr size_t kInfraCfgRegCount = MT8167_INFRACFG_SIZE / sizeof(uint32_t);

template <typename T>
ddk_mock::MockMmioReg& GetMockReg(ddk_mock::MockMmioRegRegion& registers) {
  return registers[T::Get().addr()];
}

template <typename T>
ddk_mock::MockMmioReg& GetMockReg(int index, ddk_mock::MockMmioRegRegion& registers) {
  return registers[T::Get(index).addr()];
}

constexpr fuchsia_hardware_thermal_ThermalTemperatureInfo TripPoint(float temp, uint16_t opp) {
  fuchsia_hardware_thermal_ThermalTemperatureInfo trip = {};
  trip.up_temp_celsius = temp + 2.0f;
  trip.down_temp_celsius = temp - 2.0f;
  trip.big_cluster_dvfs_opp = opp;
  return trip;
}

}  // namespace

namespace thermal {

class MtkThermalTest : public MtkThermal {
 public:
  MtkThermalTest(mmio_buffer_t dummy_mmio, const ddk::CompositeProtocolClient& composite,
                 const ddk::PDevProtocolClient& pdev,
                 const fuchsia_hardware_thermal_ThermalDeviceInfo& thermal_info, zx::port port,
                 TempCalibration0 cal0_fuse, TempCalibration1 cal1_fuse, TempCalibration2 cal2_fuse,
                 zx::port main_port, zx::port thread_port)
      : MtkThermal(nullptr, ddk::MmioBuffer(dummy_mmio), ddk::MmioBuffer(dummy_mmio),
                   ddk::MmioBuffer(dummy_mmio), ddk::MmioBuffer(dummy_mmio), composite, pdev,
                   thermal_info, std::move(port), zx::interrupt(), cal0_fuse, cal1_fuse, cal2_fuse),
        mock_thermal_regs_(thermal_reg_array_, sizeof(uint32_t), MT8167_THERMAL_SIZE),
        mock_pll_regs_(pll_reg_array_, sizeof(uint32_t), MT8167_AP_MIXED_SYS_SIZE),
        mock_pmic_wrap_regs_(pmic_wrap_reg_array_, sizeof(uint32_t), MT8167_PMIC_WRAP_SIZE),
        mock_infracfg_regs_(infracfg_reg_array_, sizeof(uint32_t), MT8167_INFRACFG_SIZE),
        main_port_(std::move(main_port)),
        thread_port_(std::move(thread_port)) {
    mmio_ = ddk::MmioBuffer(mock_thermal_regs_.GetMmioBuffer());
    pll_mmio_ = ddk::MmioBuffer(mock_pll_regs_.GetMmioBuffer());
    pmic_mmio_ = ddk::MmioBuffer(mock_pmic_wrap_regs_.GetMmioBuffer());
    infracfg_mmio_ = ddk::MmioBuffer(mock_infracfg_regs_.GetMmioBuffer());
  }

  static bool Create(const fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info, zx::port port,
                     std::unique_ptr<MtkThermalTest>* test) {
    mmio_buffer_t dummy_mmio;
    dummy_mmio.vaddr = FakeMmioPtr(&dummy_mmio);
    dummy_mmio.size = sizeof(dummy_mmio);

    TempCalibration0 cal0_fuse;
    cal0_fuse.set_reg_value(kCal0Fuse);

    TempCalibration1 cal1_fuse;
    cal1_fuse.set_reg_value(kCal1Fuse);

    TempCalibration2 cal2_fuse;
    cal2_fuse.set_reg_value(kCal2Fuse);

    zx::port main_port;
    if (zx::port::create(0, &main_port) != ZX_OK) {
      return false;
    }

    zx::port thread_port;
    if (main_port.duplicate(ZX_RIGHT_SAME_RIGHTS, &thread_port) != ZX_OK) {
      return false;
    }

    fbl::AllocChecker ac;
    test->reset(new (&ac) MtkThermalTest(dummy_mmio, ddk::CompositeProtocolClient(),
                                         ddk::PDevProtocolClient(), thermal_info, std::move(port),
                                         cal0_fuse, cal1_fuse, cal2_fuse, std::move(main_port),
                                         std::move(thread_port)));
    return ac.check();
  }

  ddk_mock::MockMmioRegRegion& thermal_regs() { return mock_thermal_regs_; }
  ddk_mock::MockMmioRegRegion& pll_regs() { return mock_pll_regs_; }
  ddk_mock::MockMmioRegRegion& pmic_wrap_regs() { return mock_pmic_wrap_regs_; }
  ddk_mock::MockMmioRegRegion& infracfg_regs() { return mock_infracfg_regs_; }

  mock_function::MockFunction<void, uint16_t, uint32_t>& mock_PmicWrite() {
    return mock_pmic_write_;
  }
  mock_function::MockFunction<float>& mock_ReadTemperatureSensors() {
    return mock_get_temperature_;
  }
  mock_function::MockFunction<zx_status_t, uint16_t>& mock_SetDvfsOpp() {
    return mock_set_dvfs_opp_;
  }
  mock_function::MockFunction<zx_status_t, size_t>& mock_SetTripPoint() {
    return mock_set_trip_point_;
  }

  void VerifyAll() {
    for (size_t i = 0; i < kThermalRegCount; i++) {
      mock_thermal_regs_[i].VerifyAndClear();
    }

    for (size_t i = 0; i < kPllRegCount; i++) {
      mock_pll_regs_[i].VerifyAndClear();
    }

    for (size_t i = 0; i < kPmicWrapRegCount; i++) {
      mock_pmic_wrap_regs_[i].VerifyAndClear();
    }

    mock_pmic_write_.VerifyAndClear();
    mock_get_temperature_.VerifyAndClear();
    mock_set_dvfs_opp_.VerifyAndClear();
  }

  void PmicWrite(uint16_t data, uint32_t addr) override {
    if (mock_pmic_write_.HasExpectations()) {
      mock_pmic_write_.Call(data, addr);
    } else {
      MtkThermal::PmicWrite(data, addr);
    }
  }

  float ReadTemperatureSensors() override {
    if (mock_get_temperature_.HasExpectations()) {
      return mock_get_temperature_.Call();
    } else {
      return MtkThermal::ReadTemperatureSensors();
    }
  }

  zx_status_t SetDvfsOpp(uint16_t op_idx) override {
    if (mock_set_dvfs_opp_.HasExpectations()) {
      return mock_set_dvfs_opp_.Call(op_idx);
    } else {
      return MtkThermal::SetDvfsOpp(op_idx);
    }
  }

  zx_status_t SetTripPoint(size_t trip_pt) override {
    if (mock_set_trip_point_.HasExpectations()) {
      return mock_set_trip_point_.Call(trip_pt);
    } else {
      return MtkThermal::SetTripPoint(trip_pt);
    }
  }

  // Trigger count interrupts without waiting for them to be handled.
  zx_status_t TriggerInterrupts(uint32_t count) {
    zx_port_packet_t packet;
    packet.key = kPacketKeyInterrupt;
    packet.type = ZX_PKT_TYPE_USER;
    packet.user.u32[0] = count;
    return main_port_.queue(&packet);
  }

  // Wait for the thread to finish processing interrupts and join.
  zx_status_t StopThread() override {
    zx_port_packet_t packet;
    packet.key = kPacketKeyStopThread;
    packet.type = ZX_PKT_TYPE_USER;
    zx_status_t status = main_port_.queue(&packet);

    JoinThread();
    return status;
  }

 private:
  // These were taken from a real device.
  static constexpr uint32_t kCal0Fuse = 0x29389d67;
  static constexpr uint32_t kCal1Fuse = 0x805f84a9;
  static constexpr uint32_t kCal2Fuse = 0x4eaad600;

  static constexpr uint64_t kPacketKeyInterrupt = 0;
  static constexpr uint64_t kPacketKeyStopThread = 1;

  zx_status_t WaitForInterrupt() override {
    if (interrupt_count_ > 0) {
      interrupt_count_--;
      return ZX_OK;
    }

    zx_port_packet_t packet;
    zx_status_t status = thread_port_.wait(zx::deadline_after(zx::duration::infinite()), &packet);
    if (status != ZX_OK) {
      return ZX_ERR_CANCELED;
    }

    if (packet.type == ZX_PKT_TYPE_USER && packet.key == kPacketKeyInterrupt) {
      interrupt_count_ = packet.user.u32[0] - 1;
      return ZX_OK;
    }

    return ZX_ERR_CANCELED;
  }

  ddk_mock::MockMmioReg thermal_reg_array_[kThermalRegCount];
  ddk_mock::MockMmioReg pll_reg_array_[kPllRegCount];
  ddk_mock::MockMmioReg pmic_wrap_reg_array_[kPmicWrapRegCount];
  ddk_mock::MockMmioReg infracfg_reg_array_[kInfraCfgRegCount];

  ddk_mock::MockMmioRegRegion mock_thermal_regs_;
  ddk_mock::MockMmioRegRegion mock_pll_regs_;
  ddk_mock::MockMmioRegRegion mock_pmic_wrap_regs_;
  ddk_mock::MockMmioRegRegion mock_infracfg_regs_;

  mock_function::MockFunction<void, uint16_t, uint32_t> mock_pmic_write_;
  mock_function::MockFunction<float> mock_get_temperature_;
  mock_function::MockFunction<zx_status_t, uint16_t> mock_set_dvfs_opp_;
  mock_function::MockFunction<zx_status_t, size_t> mock_set_trip_point_;

  uint32_t interrupt_count_ = 0;
  zx::port main_port_;
  zx::port thread_port_;
};

TEST(ThermalTest, TripPoints) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.num_trip_points = 3;
  thermal_info.critical_temp_celsius = 50.0f;
  thermal_info.trip_point_info[0] = TripPoint(20.0f, 2);
  thermal_info.trip_point_info[1] = TripPoint(30.0f, 1);
  thermal_info.trip_point_info[2] = TripPoint(40.0f, 0);

  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));

  test->mock_SetDvfsOpp().ExpectNoCall();

  uint32_t up_int = TempMonIntStatus::Get().FromValue(0).set_hot_0(1).reg_value();
  uint32_t down_int = TempMonIntStatus::Get().FromValue(0).set_cold_0(1).reg_value();

  test->mock_ReadTemperatureSensors().ExpectCall(20.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 0);

  test->mock_ReadTemperatureSensors().ExpectCall(35.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 1);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(up_int);

  test->mock_ReadTemperatureSensors().ExpectCall(45.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 2);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(up_int);

  test->mock_ReadTemperatureSensors().ExpectCall(25.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 1);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(down_int);

  test->mock_ReadTemperatureSensors().ExpectCall(15.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 0);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(down_int);

  EXPECT_OK(test->StartThread());

  EXPECT_OK(test->TriggerInterrupts(4));
  EXPECT_OK(test->StopThread());
  test->VerifyAll();
}

TEST(ThermalTest, CriticalTemperature) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.num_trip_points = 3;
  thermal_info.critical_temp_celsius = 50.0f;
  thermal_info.trip_point_info[0] = TripPoint(20.0f, 2);
  thermal_info.trip_point_info[1] = TripPoint(30.0f, 1);
  thermal_info.trip_point_info[2] = TripPoint(40.0f, 0);

  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));

  uint32_t critical_int = TempMonIntStatus::Get().FromValue(0).set_stage_3(1).reg_value();

  test->mock_ReadTemperatureSensors().ExpectCall(20.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 0);

  test->mock_ReadTemperatureSensors().ExpectCall(55.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 2);
  test->mock_SetDvfsOpp().ExpectCall(ZX_OK, 0);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(critical_int);

  EXPECT_OK(test->StartThread());

  EXPECT_OK(test->TriggerInterrupts(1));
  EXPECT_OK(test->StopThread());
  test->VerifyAll();
}

TEST(ThermalTest, InitialTripPoint) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.num_trip_points = 3;
  thermal_info.critical_temp_celsius = 50.0f;
  thermal_info.trip_point_info[0] = TripPoint(20.0f, 2);
  thermal_info.trip_point_info[1] = TripPoint(30.0f, 1);
  thermal_info.trip_point_info[2] = TripPoint(40.0f, 0);

  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));

  test->mock_ReadTemperatureSensors().ExpectCall(45.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 2);

  EXPECT_OK(test->StartThread());

  EXPECT_OK(test->StopThread());
  test->VerifyAll();
}

TEST(ThermalTest, TripPointJumpMultiple) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.num_trip_points = 5;
  thermal_info.critical_temp_celsius = 100.0f;
  thermal_info.trip_point_info[0] = TripPoint(20.0f, 4);
  thermal_info.trip_point_info[1] = TripPoint(30.0f, 3);
  thermal_info.trip_point_info[2] = TripPoint(40.0f, 2);
  thermal_info.trip_point_info[3] = TripPoint(50.0f, 1);
  thermal_info.trip_point_info[4] = TripPoint(60.0f, 0);

  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));

  uint32_t up_int = TempMonIntStatus::Get().FromValue(0).set_hot_0(1).reg_value();
  uint32_t down_int = TempMonIntStatus::Get().FromValue(0).set_cold_0(1).reg_value();

  test->mock_ReadTemperatureSensors().ExpectCall(20.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 0);

  test->mock_ReadTemperatureSensors().ExpectCall(45.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 2);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(up_int);

  test->mock_ReadTemperatureSensors().ExpectCall(65.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 4);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(up_int);

  test->mock_ReadTemperatureSensors().ExpectCall(15.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 0);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(down_int);

  test->mock_ReadTemperatureSensors().ExpectCall(55.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 3);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(up_int);

  test->mock_ReadTemperatureSensors().ExpectCall(25.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 1);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(down_int);

  test->mock_ReadTemperatureSensors().ExpectCall(65.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 4);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(up_int);

  test->mock_ReadTemperatureSensors().ExpectCall(35.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 2);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(down_int);

  test->mock_ReadTemperatureSensors().ExpectCall(15.0f);
  test->mock_SetTripPoint().ExpectCall(ZX_OK, 0);
  GetMockReg<TempMonIntStatus>(test->thermal_regs()).ExpectRead(down_int);

  EXPECT_OK(test->StartThread());

  EXPECT_OK(test->TriggerInterrupts(8));
  EXPECT_OK(test->StopThread());
  test->VerifyAll();
}

TEST(ThermalTest, SetTripPoint) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.num_trip_points = 3;
  thermal_info.trip_point_info[0] = TripPoint(20.0f, 2);
  thermal_info.trip_point_info[1] = TripPoint(30.0f, 1);
  thermal_info.trip_point_info[2] = TripPoint(40.0f, 0);

  zx::port port;
  ASSERT_OK(zx::port::create(0, &port));

  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, std::move(port), &test));

  ASSERT_OK(test->GetPort(&port));

  GetMockReg<TempHotThreshold>(test->thermal_regs()).ExpectWrite();
  GetMockReg<TempColdThreshold>(test->thermal_regs()).ExpectWrite();

  test->SetTripPoint(0);

  zx_port_packet_t packet;
  ASSERT_OK(port.wait(zx::deadline_after(zx::duration::infinite()), &packet));
  EXPECT_EQ(ZX_PKT_TYPE_USER, packet.type);
  EXPECT_EQ(0, packet.key);

  EXPECT_NE(0, GetMockReg<TempHotThreshold>(test->thermal_regs()).Read());
  EXPECT_EQ(0xfff, GetMockReg<TempColdThreshold>(test->thermal_regs()).Read());

  ASSERT_NO_FATAL_FAILURES(test->VerifyAll());

  GetMockReg<TempHotThreshold>(test->thermal_regs()).ExpectWrite();
  GetMockReg<TempColdThreshold>(test->thermal_regs()).ExpectWrite();

  test->SetTripPoint(1);

  ASSERT_OK(port.wait(zx::deadline_after(zx::duration::infinite()), &packet));
  EXPECT_EQ(ZX_PKT_TYPE_USER, packet.type);
  EXPECT_EQ(1, packet.key);

  EXPECT_NE(0, GetMockReg<TempHotThreshold>(test->thermal_regs()).Read());
  EXPECT_NE(0, GetMockReg<TempColdThreshold>(test->thermal_regs()).Read());

  ASSERT_NO_FATAL_FAILURES(test->VerifyAll());

  GetMockReg<TempHotThreshold>(test->thermal_regs()).ExpectWrite();
  GetMockReg<TempColdThreshold>(test->thermal_regs()).ExpectWrite();

  test->SetTripPoint(2);

  ASSERT_OK(port.wait(zx::deadline_after(zx::duration::infinite()), &packet));
  EXPECT_EQ(ZX_PKT_TYPE_USER, packet.type);
  EXPECT_EQ(2, packet.key);

  EXPECT_EQ(0, GetMockReg<TempHotThreshold>(test->thermal_regs()).Read());
  EXPECT_NE(0, GetMockReg<TempColdThreshold>(test->thermal_regs()).Read());

  test->VerifyAll();
}

TEST(ThermalTest, DvfsOpp) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].count = 3;
  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].opp[0] = {
      598'000'000, 1'150'000};
  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].opp[1] = {
      747'500'000, 1'150'000};
  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].opp[2] = {
      1'040'000'000, 1'200'000};

  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));

  auto voltage_to_step = [](uint32_t volt_uv) -> uint16_t {
    return static_cast<uint16_t>((volt_uv - 700'000) / 6250);
  };

  auto frequency_to_reg_value = [](uint32_t freq_hz) -> uint32_t {
    uint64_t pcw = (static_cast<uint64_t>(freq_hz) << 14) / 26'000'000;
    return (1 << 31) | static_cast<uint32_t>(pcw);
  };

  test->mock_PmicWrite().ExpectCall(voltage_to_step(1'150'000), 0x110);

  GetMockReg<ArmPllCon1>(test->pll_regs())
      .ExpectRead(frequency_to_reg_value(598'000'000))
      .ExpectWrite(frequency_to_reg_value(747'500'000));

  EXPECT_OK(test->SetDvfsOpp(1));
  EXPECT_EQ(1, test->get_dvfs_opp());

  ASSERT_NO_FATAL_FAILURES(test->VerifyAll());

  test->mock_PmicWrite().ExpectCall(voltage_to_step(1'200'000), 0x110);

  GetMockReg<ArmPllCon1>(test->pll_regs())
      .ExpectRead(frequency_to_reg_value(747'500'000))
      .ExpectWrite(frequency_to_reg_value(1'040'000'000));

  EXPECT_OK(test->SetDvfsOpp(2));
  EXPECT_EQ(2, test->get_dvfs_opp());

  ASSERT_NO_FATAL_FAILURES(test->VerifyAll());

  test->mock_PmicWrite().ExpectCall(voltage_to_step(1150000), 0x110);

  GetMockReg<ArmPllCon1>(test->pll_regs())
      .ExpectRead(frequency_to_reg_value(1'040'000'000))
      .ExpectWrite(frequency_to_reg_value(598'000'000));

  EXPECT_OK(test->SetDvfsOpp(0));
  EXPECT_EQ(0, test->get_dvfs_opp());

  test->VerifyAll();
}

TEST(ThermalTest, DvfsOppVoltageRange) {
  fuchsia_hardware_thermal_ThermalDeviceInfo thermal_info;
  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].count = 1;

  std::unique_ptr<MtkThermalTest> test;

  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].opp[0] = {
      1'000'000'000, 100'000};
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));
  EXPECT_NE(ZX_OK, test->SetDvfsOpp(0));

  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].opp[0] = {
      1'000'000'000, 1'500'000};
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));
  EXPECT_NE(ZX_OK, test->SetDvfsOpp(0));

  thermal_info.opps[fuchsia_hardware_thermal_PowerDomain_BIG_CLUSTER_POWER_DOMAIN].opp[0] = {
      1'000'000'000, 1'151'000};
  ASSERT_TRUE(MtkThermalTest::Create(thermal_info, zx::port(), &test));
  EXPECT_NE(ZX_OK, test->SetDvfsOpp(0));
}

TEST(ThermalTest, PmicWrite) {
  std::unique_ptr<MtkThermalTest> test;
  ASSERT_TRUE(MtkThermalTest::Create({}, zx::port(), &test));

  GetMockReg<PmicReadData>(test->pmic_wrap_regs())
      .ExpectRead(0x00060000)
      .ExpectRead(0x00060000)
      .ExpectRead(0x00060000)
      .ExpectRead(0x00000000);

  GetMockReg<PmicCmd>(test->pmic_wrap_regs()).ExpectWrite(0xce8761df);

  test->PmicWrite(0x61df, 0x4e87);
  ASSERT_NO_FATAL_FAILURES(test->VerifyAll());

  GetMockReg<PmicReadData>(test->pmic_wrap_regs()).ExpectRead(0x00060000).ExpectRead(0x00000000);

  GetMockReg<PmicCmd>(test->pmic_wrap_regs()).ExpectWrite(0xf374504f);

  test->PmicWrite(0x504f, 0x7374);
  test->VerifyAll();
}

}  // namespace thermal
