blob: f3b917e7025cac23f0d47aa0f60856a8c0e4bd5e [file] [log] [blame]
// Copyright 2018 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_THERMAL_DRIVERS_MTK_THERMAL_MTK_THERMAL_REG_H_
#define SRC_DEVICES_THERMAL_DRIVERS_MTK_THERMAL_MTK_THERMAL_REG_H_
#include <lib/mmio/mmio.h>
#include <hwreg/bitfields.h>
namespace thermal {
class ArmPllCon1 : public hwreg::RegisterBase<ArmPllCon1, uint32_t> {
public:
static constexpr uint32_t kDiv1 = 0;
static constexpr uint32_t kDiv2 = 1;
static constexpr uint32_t kDiv4 = 2;
static constexpr uint32_t kDiv8 = 3;
static constexpr uint32_t kDiv16 = 4;
static constexpr uint32_t kPcwFracBits = 14;
static constexpr uint32_t kPllSrcClk = 26000000;
static auto Get() { return hwreg::RegisterAddr<ArmPllCon1>(0x104); }
uint32_t frequency() const {
uint64_t freq = static_cast<uint64_t>(pcw()) * kPllSrcClk;
return static_cast<uint32_t>(freq >> (kPcwFracBits + div()));
}
ArmPllCon1& set_frequency(uint32_t freq_hz) {
set_change(1);
set_div(kDiv1);
uint64_t pcw_value = static_cast<uint64_t>(freq_hz) << (kPcwFracBits + div());
set_pcw(static_cast<uint32_t>(pcw_value / kPllSrcClk));
return *this;
}
DEF_BIT(31, change);
DEF_FIELD(26, 24, div);
DEF_FIELD(20, 0, pcw);
};
class PmicCmd : public hwreg::RegisterBase<PmicCmd, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<PmicCmd>(0xa0); }
DEF_BIT(31, write);
DEF_FIELD(30, 16, addr);
DEF_FIELD(15, 0, data);
};
class PmicReadData : public hwreg::RegisterBase<PmicReadData, uint32_t> {
public:
static constexpr uint32_t kStateIdle = 0;
static constexpr uint32_t kStateValid = 6;
static auto Get() { return hwreg::RegisterAddr<PmicReadData>(0xa4); }
DEF_FIELD(18, 16, status);
DEF_FIELD(15, 0, data);
};
class TempMonCtl0 : public hwreg::RegisterBase<TempMonCtl0, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMonCtl0>(0x00); }
DEF_BIT(3, sense3_en);
DEF_BIT(2, sense2_en);
DEF_BIT(1, sense1_en);
DEF_BIT(0, sense0_en);
TempMonCtl0& disable_all() {
set_sense0_en(0);
set_sense1_en(0);
set_sense2_en(0);
set_sense3_en(0);
return *this;
}
TempMonCtl0& enable_all() {
set_sense0_en(1);
set_sense1_en(1);
set_sense2_en(1);
set_sense3_en(1);
return *this;
}
TempMonCtl0& enable_real() {
set_sense0_en(1);
set_sense1_en(1);
set_sense2_en(1);
return *this;
}
};
class TempMonCtl1 : public hwreg::RegisterBase<TempMonCtl1, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMonCtl1>(0x04); }
DEF_FIELD(9, 0, period);
};
class TempMonCtl2 : public hwreg::RegisterBase<TempMonCtl2, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMonCtl2>(0x08); }
DEF_FIELD(25, 16, filt_interval);
DEF_FIELD(9, 0, sen_interval);
};
class TempMonInt : public hwreg::RegisterBase<TempMonInt, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMonInt>(0x0c); }
DEF_BIT(31, stage_3_en);
DEF_BIT(30, stage_2_en);
DEF_BIT(29, stage_1_en);
DEF_BIT(14, hot_to_normal_en_2);
DEF_BIT(13, high_offset_en_2);
DEF_BIT(12, low_offset_en_2);
DEF_BIT(11, hot_en_2);
DEF_BIT(10, cold_en_2);
DEF_BIT(9, hot_to_normal_en_1);
DEF_BIT(8, high_offset_en_1);
DEF_BIT(7, low_offset_en_1);
DEF_BIT(6, hot_en_1);
DEF_BIT(5, cold_en_1);
DEF_BIT(4, hot_to_normal_en_0);
DEF_BIT(3, high_offset_en_0);
DEF_BIT(2, low_offset_en_0);
DEF_BIT(1, hot_en_0);
DEF_BIT(0, cold_en_0);
};
class TempMonIntStatus : public hwreg::RegisterBase<TempMonIntStatus, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMonIntStatus>(0x10); }
DEF_BIT(31, stage_3);
DEF_BIT(30, stage_2);
DEF_BIT(29, stage_1);
DEF_BIT(14, hot_to_normal_2);
DEF_BIT(13, high_offset_2);
DEF_BIT(12, low_offset_2);
DEF_BIT(11, hot_2);
DEF_BIT(10, cold_2);
DEF_BIT(9, hot_to_normal_1);
DEF_BIT(8, high_offset_1);
DEF_BIT(7, low_offset_1);
DEF_BIT(6, hot_1);
DEF_BIT(5, cold_1);
DEF_BIT(4, hot_to_normal_0);
DEF_BIT(3, high_offset_0);
DEF_BIT(2, low_offset_0);
DEF_BIT(1, hot_0);
DEF_BIT(0, cold_0);
};
class TempHotToNormalThreshold : public hwreg::RegisterBase<TempHotToNormalThreshold, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempHotToNormalThreshold>(0x24); }
DEF_FIELD(11, 0, threshold);
};
class TempHotThreshold : public hwreg::RegisterBase<TempHotThreshold, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempHotThreshold>(0x28); }
DEF_FIELD(11, 0, threshold);
};
class TempColdThreshold : public hwreg::RegisterBase<TempColdThreshold, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempColdThreshold>(0x2c); }
DEF_FIELD(11, 0, threshold);
};
class TempOffsetHighThreshold : public hwreg::RegisterBase<TempOffsetHighThreshold, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempOffsetHighThreshold>(0x30); }
DEF_FIELD(11, 0, threshold);
};
class TempOffsetLowThreshold : public hwreg::RegisterBase<TempOffsetLowThreshold, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempOffsetLowThreshold>(0x30); }
DEF_FIELD(11, 0, threshold);
};
class TempMsrCtl0 : public hwreg::RegisterBase<TempMsrCtl0, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMsrCtl0>(0x38); }
static constexpr uint32_t kSample1 = 0;
static constexpr uint32_t kSample2 = 1;
static constexpr uint32_t kSample4Drop2 = 2;
static constexpr uint32_t kSample6Drop2 = 3;
static constexpr uint32_t kSample10Drop2 = 4;
static constexpr uint32_t kSample18Drop2 = 5;
DEF_FIELD(11, 9, msrctl3);
DEF_FIELD(8, 6, msrctl2);
DEF_FIELD(5, 3, msrctl1);
DEF_FIELD(2, 0, msrctl0);
};
class TempMsrCtl1 : public hwreg::RegisterBase<TempMsrCtl1, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempMsrCtl1>(0x3c); }
DEF_BIT(8, pause_3);
DEF_BIT(3, pause_2);
DEF_BIT(2, pause_1);
DEF_BIT(1, pause_0);
TempMsrCtl1& pause_real() {
set_pause_0(1);
set_pause_1(1);
set_pause_2(1);
return *this;
}
TempMsrCtl1& resume_real() {
set_pause_0(0);
set_pause_1(0);
set_pause_2(0);
return *this;
}
};
class TempAhbPoll : public hwreg::RegisterBase<TempAhbPoll, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAhbPoll>(0x40); }
};
class TempAhbTimeout : public hwreg::RegisterBase<TempAhbTimeout, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAhbTimeout>(0x44); }
};
class TempAdcPnp : public hwreg::RegisterBase<TempAdcPnp, uint32_t> {
public:
static auto Get(uint32_t index) { return hwreg::RegisterAddr<TempAdcPnp>(0x48 + (index * 4)); }
};
class TempAdcMux : public hwreg::RegisterBase<TempAdcMux, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcMux>(0x54); }
};
class TempAdcEn : public hwreg::RegisterBase<TempAdcEn, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcEn>(0x60); }
};
class TempPnpMuxAddr : public hwreg::RegisterBase<TempPnpMuxAddr, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempPnpMuxAddr>(0x64); }
};
class TempAdcMuxAddr : public hwreg::RegisterBase<TempAdcMuxAddr, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcMuxAddr>(0x68); }
};
class TempAdcEnAddr : public hwreg::RegisterBase<TempAdcEnAddr, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcEnAddr>(0x74); }
};
class TempAdcValidAddr : public hwreg::RegisterBase<TempAdcValidAddr, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcValidAddr>(0x78); }
};
class TempAdcVoltAddr : public hwreg::RegisterBase<TempAdcVoltAddr, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcVoltAddr>(0x7c); }
};
class TempRdCtrl : public hwreg::RegisterBase<TempRdCtrl, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempRdCtrl>(0x80); }
static constexpr uint32_t kValidVoltageSame = 0;
static constexpr uint32_t kValidVoltageDiff = 1;
DEF_BIT(0, diff);
};
class TempAdcValidMask : public hwreg::RegisterBase<TempAdcValidMask, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcValidMask>(0x84); }
static constexpr uint32_t kActiveLow = 0;
static constexpr uint32_t kActiveHigh = 1;
DEF_BIT(5, polarity);
DEF_FIELD(4, 0, pos);
};
class TempAdcVoltageShift : public hwreg::RegisterBase<TempAdcVoltageShift, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcVoltageShift>(0x88); }
DEF_FIELD(4, 0, shift);
};
class TempAdcWriteCtrl : public hwreg::RegisterBase<TempAdcWriteCtrl, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempAdcWriteCtrl>(0x8c); }
DEF_BIT(1, mux_write_en);
DEF_BIT(0, pnp_write_en);
};
class TempMsr : public hwreg::RegisterBase<TempMsr, uint32_t> {
public:
static auto Get(uint32_t index) { return hwreg::RegisterAddr<TempMsr>(0x90 + (index * 4)); }
DEF_BIT(15, valid);
DEF_FIELD(11, 0, reading);
};
class TempProtCtl : public hwreg::RegisterBase<TempProtCtl, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempProtCtl>(0xc0); }
static constexpr uint32_t kStrategyAverage = 0;
static constexpr uint32_t kStrategyMaximum = 1;
static constexpr uint32_t kStrategySelected = 2;
DEF_FIELD(19, 18, sensor);
DEF_FIELD(17, 16, strategy);
DEF_FIELD(11, 0, offset);
};
class TempProtStage3 : public hwreg::RegisterBase<TempProtStage3, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempProtStage3>(0xcc); }
DEF_FIELD(11, 0, threshold);
};
class TempSpare : public hwreg::RegisterBase<TempSpare, uint32_t> {
public:
static auto Get(uint32_t index) { return hwreg::RegisterAddr<TempSpare>(0xf0 + (index * 4)); }
};
// The following classes represent the temperature calibration fuses.
class TempCalibration0 : public hwreg::RegisterBase<TempCalibration0, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempCalibration0>(0x180); }
DEF_FIELD(31, 26, slope);
DEF_FIELD(25, 17, vts0);
DEF_FIELD(16, 8, vts1);
DEF_BIT(7, slope_sign);
DEF_FIELD(6, 1, temp_offset);
DEF_BIT(0, calibration_en);
uint32_t get_vts0() const { return vts0() + kVtsOffset; }
uint32_t get_vts1() const { return vts1() + kVtsOffset; }
private:
static constexpr uint32_t kVtsOffset = 3350;
};
class TempCalibration1 : public hwreg::RegisterBase<TempCalibration1, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempCalibration1>(0x184); }
DEF_FIELD(31, 22, adc_gain);
DEF_FIELD(21, 12, adc_offset);
DEF_BIT(2, id);
int32_t get_adc_gain() const { return adc_gain() - kAdcCalOffset; }
int32_t get_adc_offset() const { return adc_offset() - kAdcCalOffset; }
private:
static constexpr int32_t kAdcCalOffset = 512;
};
class TempCalibration2 : public hwreg::RegisterBase<TempCalibration2, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<TempCalibration2>(0x188); }
DEF_FIELD(31, 23, vts2);
DEF_FIELD(22, 14, vts3);
uint32_t get_vts2() const { return vts2() + kVtsOffset; }
uint32_t get_vts3() const { return vts3() + kVtsOffset; }
private:
static constexpr uint32_t kVtsOffset = 3350;
};
// The following classes represent registers in the (undocumented) INFRACFG block.
class InfraCfgClkMux : public hwreg::RegisterBase<InfraCfgClkMux, uint32_t> {
public:
static constexpr uint32_t kIfrClk26M = 0;
static constexpr uint32_t kIfrClkArmPll = 1;
static constexpr uint32_t kIfrClkUnivPll = 2;
static constexpr uint32_t kIfrClkMainPllDiv2 = 3;
static auto Get() { return hwreg::RegisterAddr<InfraCfgClkMux>(0x00); }
DEF_FIELD(3, 2, ifr_mux_sel);
};
// The following classes represent registers on the MT6392 PMIC.
class VprocCon10 : public hwreg::RegisterBase<VprocCon10, uint16_t> {
private:
static constexpr uint16_t kMaxVoltageStep = 0x7f;
static constexpr uint32_t kVoltageStepUv = 6250;
public:
static constexpr uint32_t kMinVoltageUv = 700000;
static constexpr uint32_t kMaxVoltageUv = kMinVoltageUv + (kVoltageStepUv * kMaxVoltageStep);
static auto Get() { return hwreg::RegisterAddr<VprocCon10>(0x110); }
uint32_t voltage() const { return (voltage_step() * kVoltageStepUv) + kMinVoltageUv; }
VprocCon10& set_voltage(uint32_t volt_uv) {
set_voltage_step(static_cast<uint16_t>((volt_uv - kMinVoltageUv) / kVoltageStepUv));
return *this;
}
DEF_FIELD(6, 0, voltage_step);
};
} // namespace thermal
#endif // SRC_DEVICES_THERMAL_DRIVERS_MTK_THERMAL_MTK_THERMAL_REG_H_