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