]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805Watchdog.c
ArmPlatformPkg/SP805WatchdogDxe: Removed late initialization capability from the...
[mirror_edk2.git] / ArmPlatformPkg / Drivers / SP805WatchdogDxe / SP805Watchdog.c
index 0eb459303f2eb956fc8d8c000a50d5aa20387eab..a9ec88c333545f0d16394167cb5ef07cfea15800 100644 (file)
@@ -1,6 +1,6 @@
 /** @file
 *
-*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
 *
 *  This program and the accompanying materials
 *  are licensed and made available under the terms and conditions of the BSD License
 #include <PiDxe.h>
 
 #include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
 #include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/UefiLib.h>
-#include <Library/IoLib.h>
 
 #include <Protocol/WatchdogTimer.h>
-#include <ArmPlatform.h>
 #include <Drivers/SP805Watchdog.h>
 
-/**
-  Interface structure for the Watchdog Architectural Protocol.
-
-  @par Protocol Description:
-  This protocol provides a service to set the amount of time to wait
-  before firing the watchdog timer, and it also provides a service to
-  register a handler that is invoked when the watchdog timer fires.
-
-  @par When the watchdog timer fires, control will be passed to a handler
-  if one has been registered.  If no handler has been registered,
-  or the registered handler returns, then the system will be
-  reset by calling the Runtime Service ResetSystem().
-
-  @param RegisterHandler
-  Registers a handler that will be called each time the
-  watchdogtimer interrupt fires.  TimerPeriod defines the minimum
-  time between timer interrupts, so TimerPeriod will also
-  be the minimum time between calls to the registered
-  handler.
-  NOTE: If the watchdog resets the system in hardware, then
-        this function will not have any chance of executing.
-
-  @param SetTimerPeriod
-  Sets the period of the timer interrupt in 100 nS units.
-  This function is optional, and may return EFI_UNSUPPORTED.
-  If this function is supported, then the timer period will
-  be rounded up to the nearest supported timer period.
-
-  @param GetTimerPeriod
-  Retrieves the period of the timer interrupt in 100 nS units.
-
-**/
-EFI_WATCHDOG_TIMER_ARCH_PROTOCOL    gWatchdogTimer = {
-  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) SP805RegisterHandler,
-  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) SP805SetTimerPeriod,
-  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) SP805GetTimerPeriod
-};
-
 EFI_EVENT                           EfiExitBootServicesEvent = (EFI_EVENT)NULL;
 
-BOOLEAN                             mSP805Initialized = FALSE;
-
 EFI_STATUS
 SP805Identify (
   VOID
   )
 {
   // Check if this is a PrimeCell Peripheral
-  if(    ( MmioRead8( SP805_WDOG_PCELL_ID0 ) != 0x0D )
-      || ( MmioRead8( SP805_WDOG_PCELL_ID1 ) != 0xF0 )
-      || ( MmioRead8( SP805_WDOG_PCELL_ID2 ) != 0x05 )
-      || ( MmioRead8( SP805_WDOG_PCELL_ID3 ) != 0xB1 ) ) {
+  if (    (MmioRead8 (SP805_WDOG_PCELL_ID0) != 0x0D)
+      ||  (MmioRead8 (SP805_WDOG_PCELL_ID1) != 0xF0)
+      ||  (MmioRead8 (SP805_WDOG_PCELL_ID2) != 0x05)
+      ||  (MmioRead8 (SP805_WDOG_PCELL_ID3) != 0xB1)) {
     return EFI_NOT_FOUND;
   }
 
   // Check if this PrimeCell Peripheral is the SP805 Watchdog Timer
-  if(    ( MmioRead8( SP805_WDOG_PERIPH_ID0 ) != 0x05 )
-      || ( MmioRead8( SP805_WDOG_PERIPH_ID1 ) != 0x18 )
-      || (( MmioRead8( SP805_WDOG_PERIPH_ID2 ) & 0x0000000F) != 0x04 )
-      || ( MmioRead8( SP805_WDOG_PERIPH_ID3 ) != 0x00 ) ) {
+  if (    (MmioRead8 (SP805_WDOG_PERIPH_ID0) != 0x05)
+      ||  (MmioRead8 (SP805_WDOG_PERIPH_ID1) != 0x18)
+      || ((MmioRead8 (SP805_WDOG_PERIPH_ID2) & 0x0000000F) != 0x04)
+      ||  (MmioRead8 (SP805_WDOG_PERIPH_ID3) != 0x00)) {
     return EFI_NOT_FOUND;
   }
 
@@ -255,14 +215,6 @@ SP805SetTimerPeriod (
   EFI_STATUS  Status = EFI_SUCCESS;
   UINT64      Ticks64bit;
 
-  // Initialize the hardware if not already done
-  if( !mSP805Initialized ) {
-    Status = SP805Initialize();
-    if (EFI_ERROR(Status)) {
-      goto EXIT;
-    }
-  }
-
   SP805Unlock();
 
   if( TimerPeriod == 0 ) {
@@ -282,10 +234,10 @@ SP805SetTimerPeriod (
     //
     // WatchdogTicks = (TimerPeriod * SP805_CLOCK_FREQUENCY) / 20 MHz ;
 
-    Ticks64bit = DivU64x32( MultU64x32( TimerPeriod, SP805_CLOCK_FREQUENCY ), 20000000 );
+    Ticks64bit = DivU64x32(MultU64x32(TimerPeriod, (UINTN)PcdGet32(PcdSP805WatchdogClockFrequencyInHz)), 20000000);
 
     // The registers in the SP805 are only 32 bits
-    if( Ticks64bit > SP805_MAX_TICKS ) {
+    if(Ticks64bit > (UINT64)0xFFFFFFFF) {
       // We could load the watchdog with the maximum supported value but
       // if a smaller value was requested, this could have the watchdog
       // triggering before it was intended.
@@ -336,14 +288,6 @@ SP805GetTimerPeriod (
     return EFI_INVALID_PARAMETER;
   }
 
-  // Initialize the hardware if not already done
-  if( !mSP805Initialized ) {
-    Status = SP805Initialize();
-    if (EFI_ERROR(Status)) {
-      goto EXIT;
-    }
-  }
-
   // Check if the watchdog is stopped
   if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) == 0 ) {
     // It is stopped, so return zero.
@@ -357,10 +301,47 @@ SP805GetTimerPeriod (
 
   *TimerPeriod = ReturnValue;
 
-  EXIT:
   return Status;
 }
 
+/**
+  Interface structure for the Watchdog Architectural Protocol.
+
+  @par Protocol Description:
+  This protocol provides a service to set the amount of time to wait
+  before firing the watchdog timer, and it also provides a service to
+  register a handler that is invoked when the watchdog timer fires.
+
+  @par When the watchdog timer fires, control will be passed to a handler
+  if one has been registered.  If no handler has been registered,
+  or the registered handler returns, then the system will be
+  reset by calling the Runtime Service ResetSystem().
+
+  @param RegisterHandler
+  Registers a handler that will be called each time the
+  watchdogtimer interrupt fires.  TimerPeriod defines the minimum
+  time between timer interrupts, so TimerPeriod will also
+  be the minimum time between calls to the registered
+  handler.
+  NOTE: If the watchdog resets the system in hardware, then
+        this function will not have any chance of executing.
+
+  @param SetTimerPeriod
+  Sets the period of the timer interrupt in 100 nS units.
+  This function is optional, and may return EFI_UNSUPPORTED.
+  If this function is supported, then the timer period will
+  be rounded up to the nearest supported timer period.
+
+  @param GetTimerPeriod
+  Retrieves the period of the timer interrupt in 100 nS units.
+
+**/
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL    gWatchdogTimer = {
+  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) SP805RegisterHandler,
+  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) SP805SetTimerPeriod,
+  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) SP805GetTimerPeriod
+};
+
 /**
   Initialize the state information for the Watchdog Timer Architectural Protocol.
 
@@ -373,49 +354,36 @@ SP805GetTimerPeriod (
 
 **/
 EFI_STATUS
+EFIAPI
 SP805Initialize (
-  VOID
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
   )
 {
   EFI_STATUS  Status;
+  EFI_HANDLE  Handle;
 
   // Check if the SP805 hardware watchdog module exists on board
   Status = SP805Identify();
-  if (EFI_ERROR( Status )) {
+  if (EFI_ERROR(Status)) {
     Status = EFI_DEVICE_ERROR;
     goto EXIT;
   }
 
   // Unlock access to the SP805 registers
-  SP805Unlock();
+  SP805Unlock ();
 
   // Stop the watchdog from triggering unexpectedly
-  SP805Stop();
+  SP805Stop ();
 
   // Set the watchdog to reset the board when triggered
-  if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_RESEN) == 0 ) {
-    MmioOr32(SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_RESEN);
+  if ((MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_RESEN) == 0) {
+    MmioOr32 (SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_RESEN);
   }
 
   // Prohibit any rogue access to SP805 registers
   SP805Lock();
-
-  mSP805Initialized = TRUE;
-
-  EXIT:
-  return Status;
-}
-
-EFI_STATUS
-EFIAPI
-SP805InstallProtocol (
-  IN EFI_HANDLE         ImageHandle,
-  IN EFI_SYSTEM_TABLE   *SystemTable
-  )
-{
-  EFI_STATUS  Status;
-  EFI_HANDLE  Handle;
-
+  
   //
   // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet.
   // This will avoid conflicts with the universal watchdog