blob: 86b65659aa4c43e5e39eda843182ef12f256bbe5 [file] [log] [blame]
// 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