]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/SP804TimerDxe/SP804Timer.c
ArmPlatformPkg: Minor code changes (comments, misspellings, coding stylei, line endings)
[mirror_edk2.git] / ArmPlatformPkg / Drivers / SP804TimerDxe / SP804Timer.c
index a28a045352cf5c6a864e23a424e78654b8236820..71b7a32d6d8e3384e0bb44173f2cfcb0a62dc223 100644 (file)
@@ -2,6 +2,7 @@
   Template for Timer Architecture Protocol driver of the ARM flavor
 
   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
   Template for Timer Architecture Protocol driver of the ARM flavor
 
   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
   
   This program and the accompanying materials                          
   are licensed and made available under the terms and conditions of the BSD License         
   
   This program and the accompanying materials                          
   are licensed and made available under the terms and conditions of the BSD License         
 #include <Protocol/HardwareInterrupt.h>
 
 #include <Drivers/SP804Timer.h>
 #include <Protocol/HardwareInterrupt.h>
 
 #include <Drivers/SP804Timer.h>
-#include <ArmPlatform.h>
+
+#define SP804_TIMER_PERIODIC_BASE     ((UINTN)PcdGet32 (PcdSP804TimerPeriodicBase))
+#define SP804_TIMER_METRONOME_BASE    ((UINTN)PcdGet32 (PcdSP804TimerMetronomeBase))
+#define SP804_TIMER_PERFORMANCE_BASE  ((UINTN)PcdGet32 (PcdSP804TimerPerformanceBase))
 
 // The notification function to call on every timer interrupt.
 
 // The notification function to call on every timer interrupt.
-volatile EFI_TIMER_NOTIFY      mTimerNotifyFunction   = (EFI_TIMER_NOTIFY)NULL;
-EFI_EVENT                       EfiExitBootServicesEvent        = (EFI_EVENT)NULL;
+EFI_TIMER_NOTIFY      mTimerNotifyFunction     = (EFI_TIMER_NOTIFY)NULL;
+EFI_EVENT             EfiExitBootServicesEvent = (EFI_EVENT)NULL;
 
 // The current period of the timer interrupt
 
 // The current period of the timer interrupt
-volatile UINT64 mTimerPeriod = 0;
+UINT64 mTimerPeriod = 0;
 
 // Cached copy of the Hardware Interrupt protocol instance
 EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
 
 // Cached copy of the Hardware Interrupt protocol instance
 EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
@@ -43,7 +47,6 @@ EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
 // Cached interrupt vector
 UINTN  gVector;
 
 // Cached interrupt vector
 UINTN  gVector;
 
-UINT32 mLastTickCount;
 
 /**
 
 
 /**
 
@@ -75,11 +78,11 @@ TimerInterruptHandler (
   OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
 
   // If the interrupt is shared then we must check if this interrupt source is the one associated to this Timer
   OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
 
   // If the interrupt is shared then we must check if this interrupt source is the one associated to this Timer
-  if (MmioRead32 (SP804_TIMER0_BASE + SP804_TIMER_MSK_INT_STS_REG) != 0) {
-    // clear the periodic interrupt
-    MmioWrite32 (SP804_TIMER0_BASE + SP804_TIMER_INT_CLR_REG, 0);
+  if (MmioRead32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_MSK_INT_STS_REG) != 0) {
+    // Clear the periodic interrupt
+    MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_INT_CLR_REG, 0);
 
 
-    // signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
+    // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
     gInterrupt->EndOfInterrupt (gInterrupt, Source);
 
     if (mTimerNotifyFunction) {
     gInterrupt->EndOfInterrupt (gInterrupt, Source);
 
     if (mTimerNotifyFunction) {
@@ -139,7 +142,7 @@ TimerDriverRegisterHandler (
 }
 
 /**
 }
 
 /**
-    Make sure all ArrmVe Timers are disabled
+    Make sure all Dual Timers are disabled
 **/
 VOID
 EFIAPI
 **/
 VOID
 EFIAPI
@@ -148,25 +151,20 @@ ExitBootServicesEvent (
   IN VOID       *Context
   )
 {
   IN VOID       *Context
   )
 {
-    // Disable timer 0 if enabled
-    if (MmioRead32(SP804_TIMER0_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
-        MmioAnd32 (SP804_TIMER0_BASE + SP804_TIMER_CONTROL_REG, 0);
-    }
-
-    // Disable timer 1 if enabled
-    if (MmioRead32(SP804_TIMER1_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
-        MmioAnd32 (SP804_TIMER1_BASE + SP804_TIMER_CONTROL_REG, 0);
-    }
+  // Disable 'Periodic Operation' timer if enabled
+  if (MmioRead32(SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
+    MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, 0);
+  }
 
 
-    // Disable timer 2 if enabled
-    if (MmioRead32(SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
-        MmioAnd32 (SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, 0);
-    }
+  // Disable 'Metronome/Delay' timer if enabled
+  if (MmioRead32(SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
+    MmioAnd32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG, 0);
+  }
 
 
-    // Disable timer 3 if enabled
-    if (MmioRead32(SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
-        MmioAnd32 (SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG, 0);
-    }
+  // Disable 'Performance' timer if enabled
+  if (MmioRead32(SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
+    MmioAnd32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG, 0);
+  }
 }
 
 /**
 }
 
 /**
@@ -208,29 +206,28 @@ TimerDriverSetTimerPeriod (
   UINT64      TimerTicks;
   
   // always disable the timer
   UINT64      TimerTicks;
   
   // always disable the timer
-  MmioAnd32 (SP804_TIMER0_BASE + SP804_TIMER_CONTROL_REG, ~SP804_TIMER_CTRL_ENABLE);
+  MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, ~SP804_TIMER_CTRL_ENABLE);
 
   if (TimerPeriod == 0) {
 
   if (TimerPeriod == 0) {
-    // leave timer disabled from above, and...
+    // Leave timer disabled from above, and...
 
 
-    // disable timer 0/1 interrupt for a TimerPeriod of 0
+    // Disable timer 0/1 interrupt for a TimerPeriod of 0
     Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector);    
   } else {  
     Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector);    
   } else {  
-    // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units / 10)
+    // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units * 10)
     TimerTicks = DivU64x32 (TimerPeriod, 10);
     TimerTicks = DivU64x32 (TimerPeriod, 10);
+    TimerTicks = MultU64x32 (TimerTicks, PcdGet32(PcdSP804TimerFrequencyInMHz));
 
     // if it's larger than 32-bits, pin to highest value
     if (TimerTicks > 0xffffffff) {
 
     // if it's larger than 32-bits, pin to highest value
     if (TimerTicks > 0xffffffff) {
-
       TimerTicks = 0xffffffff;
       TimerTicks = 0xffffffff;
-
     }
 
     // Program the SP804 timer with the new count value
     }
 
     // Program the SP804 timer with the new count value
-    MmioWrite32 (SP804_TIMER0_BASE + SP804_TIMER_LOAD_REG, TimerTicks);
+    MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_LOAD_REG, TimerTicks);
 
     // enable the timer
 
     // enable the timer
-    MmioOr32 (SP804_TIMER0_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
+    MmioOr32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
 
     // enable timer 0/1 interrupts
     Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector);    
 
     // enable timer 0/1 interrupts
     Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector);    
@@ -360,36 +357,23 @@ TimerInitialize (
   EFI_HANDLE  Handle = NULL;
   EFI_STATUS  Status;
 
   EFI_HANDLE  Handle = NULL;
   EFI_STATUS  Status;
 
+  // Set the interrupt timer number
+  gVector = PcdGet32(PcdSP804TimerPeriodicInterruptNum);
+
   // Find the interrupt controller protocol.  ASSERT if not found.
   Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
   ASSERT_EFI_ERROR (Status);
 
   // Find the interrupt controller protocol.  ASSERT if not found.
   Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
   ASSERT_EFI_ERROR (Status);
 
-  // Configure 1MHz clock
-  MmioOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER1_TIMCLK);
-
-  // configure timer 1 for free running operation, 32 bits, no prescaler, interrupt disabled
-  MmioWrite32 (SP804_TIMER1_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);
-
-  // enable the free running timer
-  MmioOr32 (SP804_TIMER1_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
-
-  // record free running tick value (should be close to 0xffffffff)
-  mLastTickCount = MmioRead32 (SP804_TIMER1_BASE + SP804_TIMER_CURRENT_REG);
-
   // Disable the timer
   Status = TimerDriverSetTimerPeriod (&gTimer, 0);
   ASSERT_EFI_ERROR (Status);
 
   // Install interrupt handler
   // Disable the timer
   Status = TimerDriverSetTimerPeriod (&gTimer, 0);
   ASSERT_EFI_ERROR (Status);
 
   // Install interrupt handler
-  gVector = TIMER01_INTERRUPT_NUM;
   Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
   ASSERT_EFI_ERROR (Status);
 
   Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
   ASSERT_EFI_ERROR (Status);
 
-  // configure periodic timer (TIMER0) for 1MHz operation
-  MmioOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER0_TIMCLK);
-
   // configure timer 0 for periodic operation, 32 bits, no prescaler, and interrupt enabled
   // configure timer 0 for periodic operation, 32 bits, no prescaler, and interrupt enabled
-  MmioWrite32 (SP804_TIMER0_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_PERIODIC | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1 | SP804_TIMER_CTRL_INT_ENABLE);
+  MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_PERIODIC | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1 | SP804_TIMER_CTRL_INT_ENABLE);
 
   // Set up default timer
   Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
 
   // Set up default timer
   Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD