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 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 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 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 108 GetPerformanceCounter ( 109 VOID 110 ) 111 { 112 return (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR); 113 } 114 115 UINT64 116 EFIAPI 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