1 //
2 // Copyright (c) 2010-2022 Antmicro
3 // Copyright (c) 2022 ION Mobility
4 //
5 //  This file is licensed under the MIT License.
6 //  Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using Antmicro.Renode.Core;
10 using Antmicro.Renode.Core.Structure.Registers;
11 using Antmicro.Renode.Peripherals.Bus;
12 
13 namespace Antmicro.Renode.Peripherals.Miscellaneous
14 {
15     // SCG - System Clock Generator
16     // This is a stub providing a bare minimum of configuration options along with some reasonable default values.
17     // It's not supposed to be understood as a fully-fledged Renode model.
18     // Note: the documentation explicitly disallows 8- and 16-bit transfers
19     public class S32K_SCG : BasicDoubleWordPeripheral, IKnownSize
20     {
S32K_SCG(IMachine machine)21         public S32K_SCG(IMachine machine) : base(machine)
22         {
23             Registers.ClockStatus.Define(this)
24                 .WithValueField(0, 4, FieldMode.Read, valueProviderCallback: _ => slowClockRatio.Value, name: "DIVSLOW")
25                 .WithValueField(4, 4, FieldMode.Read, valueProviderCallback: _ => busClockRatio.Value, name: "DIVBUS")
26                 .WithReservedBits(8, 8)
27                 .WithValueField(16, 4, FieldMode.Read, valueProviderCallback: _ => coreClockRatio.Value, name: "DIVCORE")
28                 .WithReservedBits(20, 4)
29                 .WithValueField(24, 4, FieldMode.Read, valueProviderCallback: _ => systemClockSource.Value, name: "SCS")
30                 .WithReservedBits(28, 4)
31             ;
32 
33             Registers.RunClockControl.Define(this, 0x3000001)
34                 .WithValueField(0, 4, out slowClockRatio, name: "DIVSLOW")
35                 .WithValueField(4, 4, out busClockRatio, name: "DIVBUS")
36                 .WithReservedBits(8, 8)
37                 .WithValueField(16, 4, out coreClockRatio, name: "DIVCORE")
38                 .WithReservedBits(20, 4)
39                 .WithValueField(24, 4, out systemClockSource, name: "SCS")
40                 .WithReservedBits(28, 4)
41             ;
42 
43             Registers.VLPRClockControl.Define(this)
44                 .WithValueField(0, 4, valueProviderCallback: _ => 3, name: "DIVSLOW")
45                 .WithValueField(4, 4, valueProviderCallback: _ => 1, name: "DIVBUS")
46                 .WithReservedBits(8, 8)
47                 .WithValueField(16, 4, valueProviderCallback: _ => 0, name: "DIVCORE")
48                 .WithReservedBits(20, 4)
49                 .WithValueField(24, 4, valueProviderCallback: _ => 3, name: "SCS")
50                 .WithReservedBits(28, 4)
51             ;
52 
53             Registers.HSRUNClockControl.Define(this)
54                 .WithValueField(0, 4, valueProviderCallback: _ => 3, name: "DIVSLOW")
55                 .WithValueField(4, 4, valueProviderCallback: _ => 1, name: "DIVBUS")
56                 .WithReservedBits(8, 8)
57                 .WithValueField(16, 4, valueProviderCallback: _ => 0, name: "DIVCORE")
58                 .WithReservedBits(20, 4)
59                 .WithValueField(24, 4, valueProviderCallback: _ => 3, name: "SCS")
60                 .WithReservedBits(28, 4)
61             ;
62 
63             Registers.CLKOUTConfiguration.Define(this)
64                 .WithReservedBits(0, 24)
65                 .WithValueField(24, 4, valueProviderCallback: _ => 1, name: "CLKOUTSEL")
66                 .WithReservedBits(28, 4)
67             ;
68 
69             Registers.OscillatorControlStatus.Define(this)
70                 .WithFlag(0, valueProviderCallback: _ => true, name: "SOSCEN")
71                 .WithReservedBits(1, 15)
72                 .WithFlag(16, valueProviderCallback: _ => false, name: "SOSCCM")
73                 .WithFlag(17, valueProviderCallback: _ => false, name: "SOSCCMRE")
74                 .WithReservedBits(18, 5)
75                 .WithFlag(23, valueProviderCallback: _ => false, name: "LK")
76                 .WithFlag(24, FieldMode.Read, valueProviderCallback: _ => true, name: "SOSCVLD")
77                 .WithFlag(25, FieldMode.Read, valueProviderCallback: _ => false, name: "SOSCSEL")
78                 .WithFlag(26, FieldMode.WriteOneToClear, name: "SOSCERR")
79                 .WithReservedBits(27, 5)
80             ;
81 
82             Registers.OscillatorDivide.Define(this)
83                 .WithValueField(0, 3, valueProviderCallback: _ => 1, name: "SOSCDIV1")
84                 .WithReservedBits(3, 5)
85                 .WithValueField(8, 3, valueProviderCallback: _ => 1, name: "SOSCDIV2")
86                 .WithReservedBits(11, 21)
87             ;
88 
89             Registers.SlowIRCControlStatus.Define(this, 0x3)
90                 .WithFlag(0, out slowIRCEnable, name: "SIRCEN")
91                 .WithFlag(1, name: "SIRCSTEN")
92                 .WithFlag(2, name: "SIRCLPEN")
93                 .WithReservedBits(3, 20)
94                 .WithFlag(23, name: "LK")
95                 .WithFlag(24, FieldMode.Read, valueProviderCallback: _ => slowIRCEnable.Value, name: "SIRCVLD")
96                 .WithFlag(25, FieldMode.Read, valueProviderCallback: _ => false, name: "SIRCSEL")
97                 .WithReservedBits(26, 6)
98             ;
99 
100             Registers.SlowIRCDivide.Define(this, 0x101)
101                 .WithValueField(0, 3, name: "SIRCDIV1")
102                 .WithReservedBits(3, 5)
103                 .WithValueField(8, 3, name: "SIRCDIV2")
104                 .WithReservedBits(11, 21)
105             ;
106 
107             Registers.SlowIRCConfiguration.Define(this)
108                 .WithFlag(0, name: "RANGE")
109                 .WithReservedBits(1, 30)
110             ;
111 
112             Registers.FastIRCControlStatus.Define(this)
113                 .WithFlag(0, valueProviderCallback: _ => true, name: "FIRCEN")
114                 .WithReservedBits(1, 2)
115                 .WithFlag(3, valueProviderCallback: _ => false, name: "FIRCREGOFF")
116                 .WithReservedBits(4, 19)
117                 .WithFlag(23, valueProviderCallback: _ => false, name: "LK")
118                 .WithFlag(24, FieldMode.Read, valueProviderCallback: _ => true, name: "FIRCVLD")
119                 .WithFlag(25, FieldMode.Read, valueProviderCallback: _ => true, name: "FIRCSEL")
120                 .WithFlag(26, valueProviderCallback: _ => false, name: "FIRCERR")
121                 .WithReservedBits(27, 5)
122             ;
123         }
124 
125         public long Size => 0x1000;
126 
127         private readonly IValueRegisterField systemClockSource;
128         private readonly IValueRegisterField coreClockRatio;
129         private readonly IValueRegisterField busClockRatio;
130         private readonly IValueRegisterField slowClockRatio;
131         private readonly IFlagRegisterField slowIRCEnable;
132 
133         private enum Registers
134         {
135             VersionId = 0x0,
136             Parameter = 0x4,
137             ClockStatus = 0x10,
138             RunClockControl = 0x14,
139             VLPRClockControl = 0x18,
140             HSRUNClockControl = 0x1C,
141             CLKOUTConfiguration = 0x20,
142             OscillatorControlStatus = 0x100,
143             OscillatorDivide = 0x104,
144             OscillatorConfiguration = 0x108,
145 
146             SlowIRCControlStatus = 0x200,
147             SlowIRCDivide = 0x204,
148             SlowIRCConfiguration = 0x208,
149 
150             FastIRCControlStatus = 0x300,
151             FastIRCDivide = 0x304,
152             FastIRCConfiguration = 0x308,
153             SystemPLLControlStatus = 0x600,
154             SystemPLLDivide = 0x604,
155             SystemPLLConfiguration = 0x608
156         }
157     }
158 }
159