1 /** @file
2
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <Uefi.h>
16
17 #include <Library/BaseLib.h>
18 #include <Library/TimerLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/OmapLib.h>
23
24 #include <Omap3530/Omap3530.h>
25
26 RETURN_STATUS
27 EFIAPI
TimerConstructor(VOID)28 TimerConstructor (
29 VOID
30 )
31 {
32 UINTN Timer = PcdGet32(PcdOmap35xxFreeTimer);
33 UINT32 TimerBaseAddress = TimerBase(Timer);
34
35 if ((MmioRead32 (TimerBaseAddress + GPTIMER_TCLR) & TCLR_ST_ON) == 0) {
36 // Set source clock for GPT3 & GPT4 to SYS_CLK
37 MmioOr32 (CM_CLKSEL_PER, CM_CLKSEL_PER_CLKSEL_GPT3_SYS | CM_CLKSEL_PER_CLKSEL_GPT4_SYS);
38
39 // Set count & reload registers
40 MmioWrite32 (TimerBaseAddress + GPTIMER_TCRR, 0x00000000);
41 MmioWrite32 (TimerBaseAddress + GPTIMER_TLDR, 0x00000000);
42
43 // Disable interrupts
44 MmioWrite32 (TimerBaseAddress + GPTIMER_TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_DISABLE | TIER_MAT_IT_DISABLE);
45
46 // Start Timer
47 MmioWrite32 (TimerBaseAddress + GPTIMER_TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
48
49 // Disable OMAP Watchdog timer (WDT2)
50 MmioWrite32 (WDTIMER2_BASE + WSPR, 0xAAAA);
51 DEBUG ((EFI_D_ERROR, "Magic delay to disable watchdog timers properly.\n"));
52 MmioWrite32 (WDTIMER2_BASE + WSPR, 0x5555);
53 }
54 return EFI_SUCCESS;
55 }
56
57 UINTN
58 EFIAPI
MicroSecondDelay(IN UINTN MicroSeconds)59 MicroSecondDelay (
60 IN UINTN MicroSeconds
61 )
62 {
63 UINT64 NanoSeconds;
64
65 NanoSeconds = MultU64x32(MicroSeconds, 1000);
66
67 while (NanoSeconds > (UINTN)-1) {
68 NanoSecondDelay((UINTN)-1);
69 NanoSeconds -= (UINTN)-1;
70 }
71
72 NanoSecondDelay(NanoSeconds);
73
74 return MicroSeconds;
75 }
76
77 UINTN
78 EFIAPI
NanoSecondDelay(IN UINTN NanoSeconds)79 NanoSecondDelay (
80 IN UINTN NanoSeconds
81 )
82 {
83 UINT32 Delay;
84 UINT32 StartTime;
85 UINT32 CurrentTime;
86 UINT32 ElapsedTime;
87 UINT32 TimerCountRegister;
88
89 Delay = (NanoSeconds / PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds)) + 1;
90
91 TimerCountRegister = TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR;
92
93 StartTime = MmioRead32 (TimerCountRegister);
94
95 do
96 {
97 CurrentTime = MmioRead32 (TimerCountRegister);
98 ElapsedTime = CurrentTime - StartTime;
99 } while (ElapsedTime < Delay);
100
101 NanoSeconds = ElapsedTime * PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds);
102
103 return NanoSeconds;
104 }
105
106 UINT64
107 EFIAPI
GetPerformanceCounter(VOID)108 GetPerformanceCounter (
109 VOID
110 )
111 {
112 return (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR);
113 }
114
115 UINT64
116 EFIAPI
GetPerformanceCounterProperties(OUT UINT64 * StartValue,OPTIONAL OUT UINT64 * EndValue OPTIONAL)117 GetPerformanceCounterProperties (
118 OUT UINT64 *StartValue, OPTIONAL
119 OUT UINT64 *EndValue OPTIONAL
120 )
121 {
122 if (StartValue != NULL) {
123 // Timer starts with the reload value
124 *StartValue = (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TLDR);
125 }
126
127 if (EndValue != NULL) {
128 // Timer counts up to 0xFFFFFFFF
129 *EndValue = 0xFFFFFFFF;
130 }
131
132 return PcdGet64(PcdEmbeddedPerformanceCounterFrequencyInHz);
133 }
134