72b860361bd335f8eba86a0b8d30161fb393115d
[mirror_edk2.git] / Omap35xxPkg / Library / DebugAgentTimerLib / DebugAgentTimerLib.c
1 /** @file
2 Debug Agent timer lib for OMAP 35xx.
3
4 Copyright (c) 2008-2010, Apple Inc. All rights reserved.
5
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15 #include <Base.h>
16 #include <Library/BaseLib.h>
17 #include <Library/IoLib.h>
18 #include <Library/OmapLib.h>
19 #include <Library/ArmLib.h>
20 #include <Library/PcdLib.h>
21
22 #include <Omap3530/Omap3530.h>
23
24
25 volatile UINT32 gVector;
26
27 // Cached registers
28 volatile UINT32 gTISR;
29 volatile UINT32 gTCLR;
30 volatile UINT32 gTLDR;
31 volatile UINT32 gTCRR;
32 volatile UINT32 gTIER;
33
34 VOID
35 EnableInterruptSource (
36 VOID
37 )
38 {
39 UINTN Bank;
40 UINTN Bit;
41
42 // Map vector to FIQ, IRQ is default
43 MmioWrite32 (INTCPS_ILR (gVector), 1);
44
45 Bank = gVector / 32;
46 Bit = 1UL << (gVector % 32);
47
48 MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit);
49 }
50
51 VOID
52 DisableInterruptSource (
53 VOID
54 )
55 {
56 UINTN Bank;
57 UINTN Bit;
58
59 Bank = gVector / 32;
60 Bit = 1UL << (gVector % 32);
61
62 MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
63 }
64
65
66
67 /**
68 Setup all the hardware needed for the debug agents timer.
69
70 This function is used to set up debug enviroment. It may enable interrupts.
71
72 **/
73 VOID
74 EFIAPI
75 DebugAgentTimerIntialize (
76 VOID
77 )
78 {
79 UINT32 TimerBaseAddress;
80
81
82 gVector = InterruptVectorForTimer (PcdGet32(PcdOmap35xxDebugAgentTimer));
83
84 // Set up the timer registers
85 TimerBaseAddress = TimerBase (PcdGet32(PcdOmap35xxDebugAgentTimer));
86 gTISR = TimerBaseAddress + GPTIMER_TISR;
87 gTCLR = TimerBaseAddress + GPTIMER_TCLR;
88 gTLDR = TimerBaseAddress + GPTIMER_TLDR;
89 gTCRR = TimerBaseAddress + GPTIMER_TCRR;
90 gTIER = TimerBaseAddress + GPTIMER_TIER;
91
92 DisableInterruptSource ();
93 }
94
95
96 /**
97 Set the period for the debug agent timer. Zero means disable the timer.
98
99 @param[in] TimerPeriodMilliseconds Frequency of the debug agent timer.
100
101 **/
102 VOID
103 EFIAPI
104 DebugAgentTimerSetPeriod (
105 IN UINT32 TimerPeriodMilliseconds
106 )
107 {
108 UINT64 TimerCount;
109 INT32 LoadValue;
110
111 if (TimerPeriodMilliseconds == 0) {
112 // Turn off GPTIMER3
113 MmioWrite32 (gTCLR, TCLR_ST_OFF);
114
115 DisableInterruptSource ();
116 } else {
117 // Calculate required timer count
118 TimerCount = DivU64x32(TimerPeriodMilliseconds * 1000000, PcdGet32(PcdDebugAgentTimerFreqNanoSeconds));
119
120 // Set GPTIMER5 Load register
121 LoadValue = (INT32) -TimerCount;
122 MmioWrite32 (gTLDR, LoadValue);
123 MmioWrite32 (gTCRR, LoadValue);
124
125 // Enable Overflow interrupt
126 MmioWrite32 (gTIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);
127
128 // Turn on GPTIMER3, it will reload at overflow
129 MmioWrite32 (gTCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
130
131 EnableInterruptSource ();
132 }
133 }
134
135
136 /**
137 Perform End Of Interrupt for the debug agent timer. This is called in the
138 interrupt handler after the interrupt has been processed.
139
140 **/
141 VOID
142 EFIAPI
143 DebugAgentTimerEndOfInterrupt (
144 VOID
145 )
146 {
147 // Clear all timer interrupts
148 MmioWrite32 (gTISR, TISR_CLEAR_ALL);
149
150 // Poll interrupt status bits to ensure clearing
151 while ((MmioRead32 (gTISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING);
152
153 MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWFIQAGR);
154 ArmDataSyncronizationBarrier ();
155
156 }
157
158