1 //
2 // Copyright (c) 2010-2023 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System.Collections.Generic;
8 using Antmicro.Renode.Peripherals.Bus;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Core;
11 using Antmicro.Renode.Time;
12 
13 namespace Antmicro.Renode.Peripherals.Timers
14 {
15     public class OMAP_Timer : LimitTimer, IDoubleWordPeripheral, IKnownSize
16     {
OMAP_Timer(IMachine machine, long frequency)17         public OMAP_Timer(IMachine machine, long frequency) : base(machine.ClockSource, frequency, direction: Direction.Ascending, limit: uint.MaxValue)
18         {
19             var registersMap = new Dictionary<long, DoubleWordRegister>
20             {
21                 {(long)Registers.Tidr, new DoubleWordRegister(this, 0x40000100)
22                     .WithTag("Y_MINOR", 0, 6)
23                     .WithTag("CUSTOM", 6, 2)
24                     .WithTag("X_MAJOR", 8, 3)
25                     .WithTag("R_RTL", 11, 5)
26                     .WithTag("FUNC", 16, 12)
27                     .WithReservedBits(28, 2)
28                     .WithTag("SCHEME", 30, 2)
29                 },
30                 {(long)Registers.TiocpCfg, new DoubleWordRegister(this)
31                     .WithTaggedFlag("SOFTRESET", 0)
32                     .WithTaggedFlag("EMUFREE", 1)
33                     .WithTag("IDLEMODE", 2, 2)
34                     .WithReservedBits(4, 28)
35                 },
36                 {(long)Registers.Tier, new DoubleWordRegister(this)
37                     .WithTaggedFlag("DMAEvent_Ack", 0)
38                 },
39                 {(long)Registers.Tistatr, new DoubleWordRegister(this)
40                     .WithTaggedFlag("MAT_IT_FLAG", 0)
41                     .WithTaggedFlag("OVF_IT_FLAG", 1)
42                     .WithTaggedFlag("TCAR_IT_FLAG", 2)
43                     .WithReservedBits(3, 29)
44                 },
45                 {(long)Registers.Tistat, new DoubleWordRegister(this)
46                     .WithTaggedFlag("MAT_IT_FLAG", 0)
47                     .WithTaggedFlag("OVF_IT_FLAG", 1)
48                     .WithTaggedFlag("TCAR_IT_FLAG", 2)
49                     .WithReservedBits(3, 29)
50                 },
51                 {(long)Registers.Tisr, new DoubleWordRegister(this)
52                     .WithTaggedFlag("MAT_EN_FLAG", 0)
53                     .WithTaggedFlag("OVF_EN_FLAG", 1)
54                     .WithTaggedFlag("TCAR_EN_FLAG", 2)
55                     .WithReservedBits(3, 29)
56                 },
57                 {(long)Registers.Tcicr, new DoubleWordRegister(this)
58                     .WithTaggedFlag("MAT_EN_FLAG", 0)
59                     .WithTaggedFlag("OVF_EN_FLAG", 1)
60                     .WithTaggedFlag("TCAR_EN_FLAG", 2)
61                     .WithReservedBits(3, 29)
62                 },
63                 {(long)Registers.Twer, new DoubleWordRegister(this)
64                     .WithTaggedFlag("MAT_WUP_ENA", 0)
65                     .WithTaggedFlag("OVF_WUP_ENA", 1)
66                     .WithTaggedFlag("TCAR_WUP_ENA", 2)
67                     .WithReservedBits(3, 29)
68                 },
69                 {(long)Registers.Tclr, new DoubleWordRegister(this, 0x38)
70                     .WithFlag(0, valueProviderCallback: _ => Enabled,
71                         writeCallback: (_, value) => Enabled = value, name: "ST")
72                     .WithFlag(1, valueProviderCallback: _ => AutoUpdate,
73                         writeCallback: (_, value) => AutoUpdate = value, name: "AR")
74                     .WithTag("PTV", 2, 3)
75                     .WithTaggedFlag("PRE", 5)
76                     .WithTaggedFlag("CE", 6)
77                     .WithTaggedFlag("SCPWM", 7)
78                     .WithTag("TCM", 8, 2)
79                     .WithTag("TRG", 10, 2)
80                     .WithTaggedFlag("PT", 12)
81                     .WithTaggedFlag("CAPT_MODE", 13)
82                     .WithTaggedFlag("GPO_CFG", 14)
83                     .WithReservedBits(15, 17)
84                 },
85                 {(long)Registers.Tcrr, new DoubleWordRegister(this)
86                     .WithValueField(0, 32, valueProviderCallback: _ =>
87                     {
88                         if(machine.SystemBus.TryGetCurrentCPU(out var cpu))
89                         {
90                             cpu.SyncTime();
91                         }
92                         return (uint)Value;
93                     }, writeCallback: (_, value) => Value = value, name: "TCRR")
94                 },
95                 {(long)Registers.Tldr, new DoubleWordRegister(this)
96                     .WithTag("LOAD_VALUE", 0, 32)
97                 },
98                 {(long)Registers.Ttgr, new DoubleWordRegister(this, 0xffffffff)
99                     .WithTag("TTGR_VALUE", 0, 32)
100                 },
101                 {(long)Registers.Twps, new DoubleWordRegister(this)
102                     .WithTaggedFlag("W_PEND_TCLR", 0)
103                     .WithTaggedFlag("W_PEND_TCRR", 1)
104                     .WithTaggedFlag("W_PEND_TLDR", 2)
105                     .WithTaggedFlag("W_PEND_TTGR", 3)
106                     .WithTaggedFlag("W_PEND_TMAR", 4)
107                     .WithReservedBits(5, 27)
108                 },
109                 {(long)Registers.Tmar, new DoubleWordRegister(this)
110                     .WithTag("COMPARE_VALUE", 0, 32)
111                 },
112                 {(long)Registers.Tcar1, new DoubleWordRegister(this)
113                     .WithTag("CAPTURED", 0, 32)
114                 },
115                 {(long)Registers.Tsicr, new DoubleWordRegister(this)
116                     .WithReservedBits(0, 1)
117                     .WithTaggedFlag("SFT", 1)
118                     .WithTaggedFlag("POSTED", 2)
119                     .WithReservedBits(3, 29)
120                 },
121                 {(long)Registers.Tcar2, new DoubleWordRegister(this)
122                     .WithTag("CAPTURED", 0, 32)
123                 },
124              };
125             registers = new DoubleWordRegisterCollection(this, registersMap);
126         }
127 
ReadDoubleWord(long offset)128         public uint ReadDoubleWord(long offset)
129         {
130             return registers.Read(offset);
131         }
132 
WriteDoubleWord(long offset, uint value)133         public void WriteDoubleWord(long offset, uint value)
134         {
135             registers.Write(offset, value);
136         }
137 
Reset()138         public override void Reset()
139         {
140             base.Reset();
141             registers.Reset();
142         }
143 
144         public long Size => 0x100;
145 
146         private readonly DoubleWordRegisterCollection registers;
147 
148         private enum Registers : long
149         {
150             Tidr = 0x00,
151             // gap
152             TiocpCfg = 0x10,
153             // gap
154             Tier = 0x20,
155             Tistatr = 0x24,
156             Tistat = 0x28,
157             Tisr = 0x2c,
158             Tcicr = 0x30,
159             Twer = 0x34,
160             Tclr = 0x38,
161             Tcrr = 0x3c,
162             Tldr = 0x40,
163             Ttgr = 0x44,
164             Twps = 0x48,
165             Tmar = 0x4c,
166             Tcar1 = 0x50,
167             Tsicr = 0x54,
168             Tcar2 = 0x58,
169         }
170     }
171 }
172