1 //
2 // Copyright (c) 2010-2024 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using Antmicro.Renode.Core;
8 using Antmicro.Renode.Core.Structure.Registers;
9 
10 namespace Antmicro.Renode.Peripherals.Miscellaneous
11 {
12     public class LPC_Clock0 : BasicDoubleWordPeripheral, IKnownSize
13     {
LPC_Clock0(IMachine machine)14         public LPC_Clock0(IMachine machine) : base(machine)
15         {
16             DefineRegisters();
17         }
18 
19         public long Size => 0x1000;
20 
DefineRegisters()21         private void DefineRegisters()
22         {
23             Registers.FreeRunningOscillatorControl.Define(this)
24                 .WithValueField(0, 16, out freeRunningOscillatorExpectedCount, name: "EXP_COUNT")
25                 .WithValueField(16, 5, name: "THRESH_RANGE_UP")
26                 .WithValueField(21, 5, name: "THRESH_RANGE_LOW")
27                 .WithReservedBits(26, 5)
28                 .WithFlag(31, name: "ENA_TUNE");
29 
30             Registers.FreeRunningOscillatorCapturedValue.Define(this)
31                 .WithValueField(0, 16, FieldMode.Read, name: "CAPVAL",
32                         valueProviderCallback: _ => freeRunningOscillatorExpectedCount.Value)
33                 .WithReservedBits(16, 15)
34                 // It's set to true at the end of each measurement cycle.
35                 // We set it on read, to handle situtaions, where software is waiting on new measurement.
36                 .WithFlag(31, out freeRunningOscillatorCapvalDataValid, FieldMode.ReadToSet, name: "DATA_VALID");
37 
38             Registers.FreeRunningOscillatorTrim.Define(this, 0x3bf)
39                 .WithValueField(0, 6, name: "TRIM",
40                         writeCallback: (_, __) => freeRunningOscillatorCapvalDataValid.Value = false)
41                 .WithReservedBits(6, 26);
42 
43             Registers.FreeRunningOscillatorScTrim.Define(this)
44                 .WithValueField(0, 6, name: "TRIM")
45                 .WithReservedBits(6, 26);
46 
47             Registers.FreeRunningOscillatorClockStatus.Define(this)
48                 .WithFlag(0, name: "CLK_OK", valueProviderCallback: _ => true)
49                 .WithReservedBits(1, 31);
50 
51             Registers.FreeRunningOscillatorEnable.Define(this)
52                 .WithFlag(0, name: "FRO_DIV1_O_EN")
53                 .WithFlag(1, name: "FRO_DIV2_O_EN")
54                 .WithFlag(2, name: "FRO_DIV4_O_EN")
55                 .WithFlag(3, name: "FRO_DIV8_O_EN")
56                 .WithFlag(4, name: "FRO_DIV16_O_EN")
57                 .WithReservedBits(5, 27);
58 
59             Registers.SystemOscillatorControl0.Define(this)
60                 .WithFlag(0, name: "LP_ENABLE")
61                 .WithFlag(1, name: "BYPASS_ENABLE")
62                 .WithReservedBits(2, 30);
63 
64             Registers.OscillatorClockSource.Define(this)
65                 .WithValueField(0, 3, name: "SEL")
66                 .WithReservedBits(3, 29);
67 
68             Registers.LowPowerOscilatorControl0.Define(this)
69                 .WithReservedBits(0, 31)
70                 .WithFlag(31, name: "CLKRDY", valueProviderCallback: _ => true);
71 
72             Registers.SystemPll0ClockSelect.Define(this)
73                 .WithValueField(0, 3, name: "SEL")
74                 .WithReservedBits(3, 29);
75 
76             Registers.SystemPll0ClockControl0.Define(this)
77                 .WithTaggedFlag("BYPASS", 0)
78                 .WithTaggedFlag("RESET", 1)
79                 .WithReservedBits(2, 11)
80                 .WithFlag(13, name: "HOLDRINGOFF_ENA")
81                 .WithReservedBits(14, 2)
82                 .WithValueField(16, 8, name: "MULT")
83                 .WithReservedBits(24, 8);
84 
85             Registers.SystemPll0Numerator.Define(this)
86                 .WithValueField(0, 30, name: "NUM")
87                 .WithReservedBits(30, 2);
88 
89             Registers.SystemPll0Denominator.Define(this)
90                 .WithValueField(0, 30, name: "DENOM")
91                 .WithReservedBits(30, 2);
92 
93             Registers.SystemPll0Pfd.Define(this)
94                 .WithValueField(0, 6, name: "PFD0")
95                 .WithFlag(6, name: "PFD0_CLKRDY", valueProviderCallback: _ => true)
96                 .WithFlag(7, name: "PFD0_CLKGATE")
97                 .WithValueField(8, 6, name: "PFD1")
98                 .WithFlag(14, name: "PFD1_CLKRDY", valueProviderCallback: _ => true)
99                 .WithFlag(15, name: "PFD1_CLKGATE")
100                 .WithValueField(16, 6, name: "PFD2")
101                 .WithFlag(22, name: "PFD2_CLKRDY", valueProviderCallback: _ => true)
102                 .WithFlag(23, name: "PFD2_CLKGATE")
103                 .WithValueField(24, 6, name: "PFD3")
104                 .WithFlag(30, name: "PFD3_CLKRDY", valueProviderCallback: _ => true)
105                 .WithFlag(31, name: "PFD3_CLKGATE");
106 
107             Registers.Aux0PllClockDivider.Define(this)
108                 .WithValueField(0, 8, name: "DIV")
109                 .WithReservedBits(8, 21)
110                 .WithTaggedFlag("RESET", 29)
111                 .WithTaggedFlag("HALT", 30)
112                 .WithTaggedFlag("REQFLAG", 31);
113 
114             Registers.Aux1PllClockDivider.Define(this)
115                 .WithValueField(0, 8, name: "DIV")
116                 .WithReservedBits(8, 21)
117                 .WithTaggedFlag("RESET", 29)
118                 .WithTaggedFlag("HALT", 30)
119                 .WithTaggedFlag("REQFLAG", 31);
120 
121             Registers.SystemCpuAhbClockDivider.Define(this)
122                 .WithValueField(0, 8, name: "DIV")
123                 .WithReservedBits(8, 23)
124                 .WithTaggedFlag("REQFLAG", 31);
125 
126             Registers.MainClockSelectA.Define(this)
127                 .WithValueField(0, 3, name: "SEL")
128                 .WithReservedBits(3, 29);
129 
130             Registers.MainClockSelectB.Define(this)
131                 .WithValueField(0, 3, name: "SEL")
132                 .WithReservedBits(3, 29);
133 
134             Registers.HighSpeedUsbClockDivider0.Define(this)
135                 .WithValueField(0, 8, name: "DIV")
136                 .WithReservedBits(8, 21)
137                 .WithTaggedFlag("RESET", 29)
138                 .WithTaggedFlag("HALT", 30)
139                 .WithTaggedFlag("REQFLAG", 31);
140 
141             Registers.HighSpeedUsbClockDivider1.Define(this)
142                 .WithValueField(0, 8, name: "DIV")
143                 .WithReservedBits(8, 21)
144                 .WithTaggedFlag("RESET", 29)
145                 .WithTaggedFlag("HALT", 30)
146                 .WithTaggedFlag("REQFLAG", 31);
147 
148             Registers.FlexSpi0ClockSelect.Define(this)
149                 .WithValueField(0, 3, name: "SEL")
150                 .WithReservedBits(3, 29);
151 
152             Registers.FlexSpi0ClockDivider.Define(this)
153                 .WithValueField(0, 8, name: "DIV")
154                 .WithReservedBits(8, 21)
155                 .WithTaggedFlag("RESET", 29)
156                 .WithTaggedFlag("HALT", 30)
157                 .WithTaggedFlag("REQFLAG", 31);
158 
159             Registers.FlexSpi1ClockSelect.Define(this)
160                 .WithValueField(0, 3, name: "SEL")
161                 .WithReservedBits(3, 29);
162 
163             Registers.FlexSpi1ClockDivider.Define(this)
164                 .WithValueField(0, 8, name: "DIV")
165                 .WithReservedBits(8, 21)
166                 .WithTaggedFlag("RESET", 29)
167                 .WithTaggedFlag("HALT", 30)
168                 .WithTaggedFlag("REQFLAG", 31);
169 
170             Registers.Sdio0FunctionalClockSelect.Define(this)
171                 .WithValueField(0, 3, name: "SEL")
172                 .WithReservedBits(3, 29);
173 
174             Registers.Sdio0FunctionalClockDivider.Define(this)
175                 .WithValueField(0, 8, name: "DIV")
176                 .WithReservedBits(8, 21)
177                 .WithTaggedFlag("RESET", 29)
178                 .WithTaggedFlag("HALT", 30)
179                 .WithTaggedFlag("REQFLAG", 31);
180 
181             Registers.Sdio1FunctionalClockSelect.Define(this)
182                 .WithValueField(0, 3, name: "SEL")
183                 .WithReservedBits(3, 29);
184 
185             Registers.Sdio1FunctionalClockDivider.Define(this)
186                 .WithValueField(0, 8, name: "DIV")
187                 .WithReservedBits(8, 21)
188                 .WithTaggedFlag("RESET", 29)
189                 .WithTaggedFlag("HALT", 30)
190                 .WithTaggedFlag("REQFLAG", 31);
191 
192             Registers.Adc0ClockSelect0.Define(this)
193                 .WithValueField(0, 3, name: "SEL")
194                 .WithReservedBits(3, 29);
195 
196             Registers.Adc0ClockSelect1.Define(this)
197                 .WithValueField(0, 3, name: "SEL")
198                 .WithReservedBits(3, 29);
199 
200             Registers.Adc0ClockDivider.Define(this)
201                 .WithValueField(0, 8, name: "DIV")
202                 .WithReservedBits(8, 21)
203                 .WithTaggedFlag("RESET", 29)
204                 .WithTaggedFlag("HALT", 30)
205                 .WithTaggedFlag("REQFLAG", 31);
206 
207             Registers.SystickFunctionalClockDivider.Define(this)
208                 .WithValueField(0, 8, name: "DIV")
209                 .WithReservedBits(8, 21)
210                 .WithTaggedFlag("RESET", 29)
211                 .WithTaggedFlag("HALT", 30)
212                 .WithTaggedFlag("REQFLAG", 31);
213         }
214 
215         private IValueRegisterField freeRunningOscillatorExpectedCount;
216         private IFlagRegisterField freeRunningOscillatorCapvalDataValid;
217 
218         private enum Registers
219         {
220             FreeRunningOscillatorControl        = 0x080,
221             FreeRunningOscillatorCapturedValue  = 0x084,
222             FreeRunningOscillatorTrim           = 0x08c,
223             FreeRunningOscillatorScTrim         = 0x090,
224             FreeRunningOscillatorClockStatus    = 0x10c,
225             FreeRunningOscillatorEnable         = 0x110,
226             SystemOscillatorControl0            = 0x160,
227             OscillatorClockSource               = 0x168,
228             LowPowerOscilatorControl0           = 0x190,
229             SystemPll0ClockSelect               = 0x200,
230             SystemPll0ClockControl0             = 0x204,
231             SystemPll0Numerator                 = 0x210,
232             SystemPll0Denominator               = 0x214,
233             SystemPll0Pfd                       = 0x218,
234             Aux0PllClockDivider                 = 0x248,
235             Aux1PllClockDivider                 = 0x24c,
236             SystemCpuAhbClockDivider            = 0x400,
237             MainClockSelectA                    = 0x430,
238             MainClockSelectB                    = 0x434,
239             HighSpeedUsbClockDivider0           = 0x500,
240             HighSpeedUsbClockDivider1           = 0x504,
241             FlexSpi0ClockSelect                 = 0x620,
242             FlexSpi0ClockDivider                = 0x624,
243             FlexSpi1ClockSelect                 = 0x630,
244             FlexSpi1ClockDivider                = 0x634,
245             Sdio0FunctionalClockSelect          = 0x680,
246             Sdio0FunctionalClockDivider         = 0x684,
247             Sdio1FunctionalClockSelect          = 0x690,
248             Sdio1FunctionalClockDivider         = 0x694,
249             Adc0ClockSelect0                    = 0x6d0,
250             Adc0ClockSelect1                    = 0x6d4,
251             Adc0ClockDivider                    = 0x6d8,
252             SystickFunctionalClockDivider       = 0x764,
253         }
254     }
255 }
256