1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <hwreg/bitfields.h> 8 9 namespace thermal { 10 11 class ArmPllCon1 : public hwreg::RegisterBase<ArmPllCon1, uint32_t> { 12 public: 13 static constexpr uint32_t kDiv1 = 0; 14 static constexpr uint32_t kDiv2 = 1; 15 static constexpr uint32_t kDiv4 = 2; 16 static constexpr uint32_t kDiv8 = 3; 17 static constexpr uint32_t kDiv16 = 4; 18 19 static constexpr uint32_t kPcwFracBits = 14; 20 21 static constexpr uint32_t kPllSrcClk = 26000000; 22 Get()23 static auto Get() { return hwreg::RegisterAddr<ArmPllCon1>(0x104); } 24 frequency()25 uint32_t frequency() const { 26 uint64_t freq = static_cast<uint64_t>(pcw()) * kPllSrcClk; 27 return static_cast<uint32_t>(freq >> (kPcwFracBits + div())); 28 } 29 set_frequency(uint32_t freq_hz)30 ArmPllCon1& set_frequency(uint32_t freq_hz) { 31 set_change(1); 32 set_div(kDiv1); 33 uint64_t pcw_value = static_cast<uint64_t>(freq_hz) << (kPcwFracBits + div()); 34 set_pcw(static_cast<uint32_t>(pcw_value / kPllSrcClk)); 35 return *this; 36 } 37 38 DEF_BIT(31, change); 39 DEF_FIELD(26, 24, div); 40 DEF_FIELD(20, 0, pcw); 41 }; 42 43 class PmicCmd : public hwreg::RegisterBase<PmicCmd, uint32_t> { 44 public: Get()45 static auto Get() { return hwreg::RegisterAddr<PmicCmd>(0xa0); } 46 47 DEF_BIT(31, write); 48 DEF_FIELD(30, 16, addr); 49 DEF_FIELD(15, 0, data); 50 }; 51 52 class PmicReadData : public hwreg::RegisterBase<PmicReadData, uint32_t> { 53 public: 54 static constexpr uint32_t kStateIdle = 0; 55 static constexpr uint32_t kStateValid = 6; 56 Get()57 static auto Get() { return hwreg::RegisterAddr<PmicReadData>(0xa4); } 58 59 DEF_FIELD(18, 16, status); 60 DEF_FIELD(15, 0, data); 61 }; 62 63 class PmicValidClear : public hwreg::RegisterBase<PmicValidClear, uint32_t> { 64 public: Get()65 static auto Get() { return hwreg::RegisterAddr<PmicValidClear>(0xa8); } 66 67 DEF_BIT(0, valid_clear); 68 }; 69 70 class TempMonCtl0 : public hwreg::RegisterBase<TempMonCtl0, uint32_t> { 71 public: Get()72 static auto Get() { return hwreg::RegisterAddr<TempMonCtl0>(0x00); } 73 74 DEF_BIT(3, sense3_en); 75 DEF_BIT(2, sense2_en); 76 DEF_BIT(1, sense1_en); 77 DEF_BIT(0, sense0_en); 78 disable_all()79 TempMonCtl0& disable_all() { 80 set_sense0_en(0); 81 set_sense1_en(0); 82 set_sense2_en(0); 83 set_sense3_en(0); 84 return *this; 85 } 86 enable_all()87 TempMonCtl0& enable_all() { 88 set_sense0_en(1); 89 set_sense1_en(1); 90 set_sense2_en(1); 91 set_sense3_en(1); 92 return *this; 93 } 94 enable_real()95 TempMonCtl0& enable_real() { 96 set_sense0_en(1); 97 set_sense1_en(1); 98 set_sense2_en(1); 99 return *this; 100 } 101 }; 102 103 class TempMonCtl1 : public hwreg::RegisterBase<TempMonCtl1, uint32_t> { 104 public: Get()105 static auto Get() { return hwreg::RegisterAddr<TempMonCtl1>(0x04); } 106 107 DEF_FIELD(9, 0, period); 108 }; 109 110 class TempMonCtl2 : public hwreg::RegisterBase<TempMonCtl2, uint32_t> { 111 public: Get()112 static auto Get() { return hwreg::RegisterAddr<TempMonCtl2>(0x08); } 113 114 DEF_FIELD(25, 16, filt_interval); 115 DEF_FIELD(9, 0, sen_interval); 116 }; 117 118 class TempMsrCtl0 : public hwreg::RegisterBase<TempMsrCtl0, uint32_t> { 119 public: Get()120 static auto Get() { return hwreg::RegisterAddr<TempMsrCtl0>(0x38); } 121 122 static constexpr uint32_t kSample1 = 0; 123 static constexpr uint32_t kSample2 = 1; 124 static constexpr uint32_t kSample4Drop2 = 2; 125 static constexpr uint32_t kSample6Drop2 = 3; 126 static constexpr uint32_t kSample10Drop2 = 4; 127 static constexpr uint32_t kSample18Drop2 = 5; 128 129 DEF_FIELD(11, 9, msrctl3); 130 DEF_FIELD(8, 6, msrctl2); 131 DEF_FIELD(5, 3, msrctl1); 132 DEF_FIELD(2, 0, msrctl0); 133 }; 134 135 class TempAhbPoll : public hwreg::RegisterBase<TempAhbPoll, uint32_t> { 136 public: Get()137 static auto Get() { return hwreg::RegisterAddr<TempAhbPoll>(0x40); } 138 }; 139 140 class TempAhbTimeout : public hwreg::RegisterBase<TempAhbTimeout, uint32_t> { 141 public: Get()142 static auto Get() { return hwreg::RegisterAddr<TempAhbTimeout>(0x44); } 143 }; 144 145 class TempAdcPnp : public hwreg::RegisterBase<TempAdcPnp, uint32_t> { 146 public: Get(uint32_t index)147 static auto Get(uint32_t index) { return hwreg::RegisterAddr<TempAdcPnp>(0x48 + (index * 4)); } 148 }; 149 150 class TempAdcMux : public hwreg::RegisterBase<TempAdcMux, uint32_t> { 151 public: Get()152 static auto Get() { return hwreg::RegisterAddr<TempAdcMux>(0x54); } 153 }; 154 155 class TempAdcEn : public hwreg::RegisterBase<TempAdcEn, uint32_t> { 156 public: Get()157 static auto Get() { return hwreg::RegisterAddr<TempAdcEn>(0x60); } 158 }; 159 160 class TempPnpMuxAddr : public hwreg::RegisterBase<TempPnpMuxAddr, uint32_t> { 161 public: Get()162 static auto Get() { return hwreg::RegisterAddr<TempPnpMuxAddr>(0x64); } 163 }; 164 165 class TempAdcMuxAddr : public hwreg::RegisterBase<TempAdcMuxAddr, uint32_t> { 166 public: Get()167 static auto Get() { return hwreg::RegisterAddr<TempAdcMuxAddr>(0x68); } 168 }; 169 170 class TempAdcEnAddr : public hwreg::RegisterBase<TempAdcEnAddr, uint32_t> { 171 public: Get()172 static auto Get() { return hwreg::RegisterAddr<TempAdcEnAddr>(0x74); } 173 }; 174 175 class TempAdcValidAddr : public hwreg::RegisterBase<TempAdcValidAddr, uint32_t> { 176 public: Get()177 static auto Get() { return hwreg::RegisterAddr<TempAdcValidAddr>(0x78); } 178 }; 179 180 class TempAdcVoltAddr : public hwreg::RegisterBase<TempAdcVoltAddr, uint32_t> { 181 public: Get()182 static auto Get() { return hwreg::RegisterAddr<TempAdcVoltAddr>(0x7c); } 183 }; 184 185 class TempRdCtrl : public hwreg::RegisterBase<TempRdCtrl, uint32_t> { 186 public: Get()187 static auto Get() { return hwreg::RegisterAddr<TempRdCtrl>(0x80); } 188 189 static constexpr uint32_t kValidVoltageSame = 0; 190 static constexpr uint32_t kValidVoltageDiff = 1; 191 192 DEF_BIT(0, diff); 193 }; 194 195 class TempAdcValidMask : public hwreg::RegisterBase<TempAdcValidMask, uint32_t> { 196 public: Get()197 static auto Get() { return hwreg::RegisterAddr<TempAdcValidMask>(0x84); } 198 199 static constexpr uint32_t kActiveLow = 0; 200 static constexpr uint32_t kActiveHigh = 1; 201 202 DEF_BIT(5, polarity); 203 DEF_FIELD(4, 0, pos); 204 }; 205 206 class TempAdcVoltageShift : public hwreg::RegisterBase<TempAdcVoltageShift, uint32_t> { 207 public: Get()208 static auto Get() { return hwreg::RegisterAddr<TempAdcVoltageShift>(0x88); } 209 210 DEF_FIELD(4, 0, shift); 211 }; 212 213 class TempAdcWriteCtrl : public hwreg::RegisterBase<TempAdcWriteCtrl, uint32_t> { 214 public: Get()215 static auto Get() { return hwreg::RegisterAddr<TempAdcWriteCtrl>(0x8c); } 216 217 DEF_BIT(1, mux_write_en); 218 DEF_BIT(0, pnp_write_en); 219 }; 220 221 class TempMsr : public hwreg::RegisterBase<TempMsr, uint32_t> { 222 public: Get(uint32_t index)223 static auto Get(uint32_t index) { return hwreg::RegisterAddr<TempMsr>(0x90 + (index * 4)); } 224 225 DEF_BIT(15, valid); 226 DEF_FIELD(11, 0, reading); 227 }; 228 229 class TempSpare : public hwreg::RegisterBase<TempSpare, uint32_t> { 230 public: Get(uint32_t index)231 static auto Get(uint32_t index) { return hwreg::RegisterAddr<TempSpare>(0xf0 + (index * 4)); } 232 }; 233 234 // The following classes represent the temperature calibration fuses. 235 class TempCalibration0 : public hwreg::RegisterBase<TempCalibration0, uint32_t> { 236 public: Get()237 static auto Get() { return hwreg::RegisterAddr<TempCalibration0>(0x180); } 238 239 DEF_FIELD(31, 26, slope); 240 DEF_FIELD(25, 17, vts0); 241 DEF_FIELD(16, 8, vts1); 242 DEF_BIT(7, slope_sign); 243 DEF_FIELD(6, 1, temp_offset); 244 DEF_BIT(0, calibration_en); 245 get_vts0()246 uint32_t get_vts0() const { return vts0() + kVtsOffset; } get_vts1()247 uint32_t get_vts1() const { return vts1() + kVtsOffset; } 248 249 private: 250 static constexpr uint32_t kVtsOffset = 3350; 251 }; 252 253 class TempCalibration1 : public hwreg::RegisterBase<TempCalibration1, uint32_t> { 254 public: Get()255 static auto Get() { return hwreg::RegisterAddr<TempCalibration1>(0x184); } 256 257 DEF_FIELD(31, 22, adc_gain); 258 DEF_FIELD(21, 12, adc_offset); 259 DEF_BIT(2, id); 260 get_adc_gain()261 int32_t get_adc_gain() const { return adc_gain() - kAdcCalOffset; } get_adc_offset()262 int32_t get_adc_offset() const { return adc_offset() - kAdcCalOffset; } 263 264 private: 265 static constexpr int32_t kAdcCalOffset = 512; 266 }; 267 268 class TempCalibration2 : public hwreg::RegisterBase<TempCalibration2, uint32_t> { 269 public: Get()270 static auto Get() { return hwreg::RegisterAddr<TempCalibration2>(0x188); } 271 272 DEF_FIELD(31, 23, vts2); 273 DEF_FIELD(22, 14, vts3); 274 get_vts2()275 uint32_t get_vts2() const { return vts2() + kVtsOffset; } get_vts3()276 uint32_t get_vts3() const { return vts3() + kVtsOffset; } 277 278 private: 279 static constexpr uint32_t kVtsOffset = 3350; 280 }; 281 282 // The following classes represent registers on the MT6392 PMIC. 283 class VprocCon10 : public hwreg::RegisterBase<VprocCon10, uint16_t> { 284 private: 285 static constexpr uint16_t kMaxVoltageStep = 0x7f; 286 static constexpr uint32_t kVoltageStepUv = 6250; 287 288 public: 289 static constexpr uint32_t kMinVoltageUv = 700000; 290 static constexpr uint32_t kMaxVoltageUv = kMinVoltageUv + (kVoltageStepUv * kMaxVoltageStep); 291 Get()292 static auto Get() { return hwreg::RegisterAddr<VprocCon10>(0x110); } 293 voltage()294 uint32_t voltage() const { 295 return (voltage_step() * kVoltageStepUv) + kMinVoltageUv; 296 } 297 set_voltage(uint32_t volt_uv)298 VprocCon10& set_voltage(uint32_t volt_uv) { 299 set_voltage_step(static_cast<uint16_t>((volt_uv - kMinVoltageUv) / kVoltageStepUv)); 300 return *this; 301 } 302 303 DEF_FIELD(6, 0, voltage_step); 304 }; 305 306 } // namespace thermal 307