Home | History | Annotate | Download | only in Omap35xxTimerLib
      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