1 /** @file
2   Debug Agent timer lib for OMAP 35xx.
3 
4   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5 
6   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
EnableInterruptSource(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
DisableInterruptSource(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
DebugAgentTimerIntialize(VOID)75 DebugAgentTimerIntialize (
76   VOID
77   )
78 {
79   UINT32      TimerBaseAddress;
80   UINT32      TimerNumber;
81 
82   TimerNumber = PcdGet32(PcdOmap35xxDebugAgentTimer);
83   gVector = InterruptVectorForTimer (TimerNumber);
84 
85   // Set up the timer registers
86   TimerBaseAddress = TimerBase (TimerNumber);
87   gTISR = TimerBaseAddress + GPTIMER_TISR;
88   gTCLR = TimerBaseAddress + GPTIMER_TCLR;
89   gTLDR = TimerBaseAddress + GPTIMER_TLDR;
90   gTCRR = TimerBaseAddress + GPTIMER_TCRR;
91   gTIER = TimerBaseAddress + GPTIMER_TIER;
92 
93   if ((TimerNumber < 2) || (TimerNumber > 9)) {
94     // This code assumes one the General Purpose timers is used
95     // GPT2 - GPT9
96     CpuDeadLoop ();
97   }
98   // Set source clock for GPT2 - GPT9 to SYS_CLK
99   MmioOr32 (CM_CLKSEL_PER, 1 << (TimerNumber - 2));
100 
101 }
102 
103 
104 /**
105   Set the period for the debug agent timer. Zero means disable the timer.
106 
107   @param[in] TimerPeriodMilliseconds    Frequency of the debug agent timer.
108 
109 **/
110 VOID
111 EFIAPI
DebugAgentTimerSetPeriod(IN UINT32 TimerPeriodMilliseconds)112 DebugAgentTimerSetPeriod (
113   IN  UINT32  TimerPeriodMilliseconds
114   )
115 {
116   UINT64      TimerCount;
117   INT32       LoadValue;
118 
119   if (TimerPeriodMilliseconds == 0) {
120     // Turn off GPTIMER3
121     MmioWrite32 (gTCLR, TCLR_ST_OFF);
122 
123     DisableInterruptSource ();
124   } else {
125     // Calculate required timer count
126     TimerCount = DivU64x32(TimerPeriodMilliseconds * 1000000, PcdGet32(PcdDebugAgentTimerFreqNanoSeconds));
127 
128     // Set GPTIMER5 Load register
129     LoadValue = (INT32) -TimerCount;
130     MmioWrite32 (gTLDR, LoadValue);
131     MmioWrite32 (gTCRR, LoadValue);
132 
133     // Enable Overflow interrupt
134     MmioWrite32 (gTIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);
135 
136     // Turn on GPTIMER3, it will reload at overflow
137     MmioWrite32 (gTCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
138 
139     EnableInterruptSource ();
140   }
141 }
142 
143 
144 /**
145   Perform End Of Interrupt for the debug agent timer. This is called in the
146   interrupt handler after the interrupt has been processed.
147 
148 **/
149 VOID
150 EFIAPI
DebugAgentTimerEndOfInterrupt(VOID)151 DebugAgentTimerEndOfInterrupt (
152   VOID
153   )
154 {
155    // Clear all timer interrupts
156   MmioWrite32 (gTISR, TISR_CLEAR_ALL);
157 
158   // Poll interrupt status bits to ensure clearing
159   while ((MmioRead32 (gTISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING);
160 
161   MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWFIQAGR);
162   ArmDataSynchronizationBarrier ();
163 
164 }
165 
166