123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /*++
- Copyright (c) 2015 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- timer.c
- Abstract:
- This module implements support for the BCM2709 timer services.
- Author:
- Chris Stevens 18-Mar-2015
- Environment:
- Firmware
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <uefifw.h>
- #include <dev/bcm2709.h>
- //
- // --------------------------------------------------------------------- Macros
- //
- //
- // This macro reads from a BCM2709 ARM timer.
- //
- #define READ_ARM_TIMER_REGISTER(_Register) \
- EfiReadRegister32(BCM2709_ARM_TIMER_BASE + (_Register))
- //
- // This macro writes to a BCM2709 ARM timer.
- //
- #define WRITE_ARM_TIMER_REGISTER(_Register, _Value) \
- EfiWriteRegister32(BCM2709_ARM_TIMER_BASE + (_Register), (_Value))
- //
- // This macro reads from a BCM2709 System timer.
- //
- #define READ_SYSTEM_TIMER_REGISTER(_Register) \
- EfiReadRegister32(BCM2709_SYSTEM_TIMER_BASE + (_Register))
- //
- // This macro writes to a BCM2709 System timer.
- //
- #define WRITE_SYSTEM_TIMER_REGISTER(_Register, _Value) \
- EfiWriteRegister32(BCM2709_SYSTEM_TIMER_BASE + (_Register), (_Value))
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- EFI_STATUS
- EfipBcm2709TimerInitialize (
- PBCM2709_TIMER Timer
- )
- /*++
- Routine Description:
- This routine initializes a BCM2709 timer.
- Arguments:
- Timer - Supplies the pointer to the timer data.
- Return Value:
- Status code.
- --*/
- {
- UINT32 ControlValue;
- //
- // The BCM2709 device library must be initialized first.
- //
- if (EfiBcm2709Initialized == FALSE) {
- return EFI_NOT_READY;
- }
- //
- // Program the default timer with no interrupt generation. There is nothing
- // to be done for the System Timer's free-running counter. It is already
- // enabled.
- //
- if (Timer->ClockTimer != FALSE) {
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerPredivider, Timer->Predivider);
- ControlValue = READ_ARM_TIMER_REGISTER(Bcm2709ArmTimerControl);
- ControlValue &= ~BCM2709_ARM_TIMER_CONTROL_INTERRUPT_ENABLE;
- ControlValue |= (BCM2709_ARM_TIMER_CONTROL_ENABLED |
- BCM2709_ARM_TIMER_CONTROL_DIVIDE_BY_1 |
- BCM2709_ARM_TIMER_CONTROL_32_BIT);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerControl, ControlValue);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerInterruptClear, 1);
- }
- return EFI_SUCCESS;
- }
- UINT64
- EfipBcm2709TimerRead (
- PBCM2709_TIMER Timer
- )
- /*++
- Routine Description:
- This routine returns the hardware counter's raw value.
- Arguments:
- Timer - Supplies the pointer to the timer data.
- Return Value:
- Returns the timer's current count.
- --*/
- {
- UINT32 Value;
- if (Timer->ClockTimer != FALSE) {
- Value = 0xFFFFFFFF;
- Value -= READ_ARM_TIMER_REGISTER(Bcm2709ArmTimerCurrentValue);
- } else {
- Value = READ_SYSTEM_TIMER_REGISTER(Bcm2709SystemTimerCounterLow);
- }
- return Value;
- }
- VOID
- EfipBcm2709TimerArm (
- PBCM2709_TIMER Timer,
- UINT64 TickCount
- )
- /*++
- Routine Description:
- This routine arms the timer to fire an interrupt after the specified number
- of ticks.
- Arguments:
- Timer - Supplies the pointer to the timer data.
- Periodic - Supplies a boolean indicating if the timer should be armed
- periodically or one-shot.
- TickCount - Supplies the interval, in ticks, from now for the timer to fire
- in.
- Return Value:
- None.
- --*/
- {
- UINT32 ControlValue;
- if (Timer->ClockTimer == FALSE) {
- return;
- }
- //
- // Set up the control value to program.
- //
- ControlValue = READ_ARM_TIMER_REGISTER(Bcm2709ArmTimerControl);
- ControlValue |= (BCM2709_ARM_TIMER_CONTROL_ENABLED |
- BCM2709_ARM_TIMER_CONTROL_DIVIDE_BY_1 |
- BCM2709_ARM_TIMER_CONTROL_32_BIT |
- BCM2709_ARM_TIMER_CONTROL_INTERRUPT_ENABLE);
- //
- // Set the timer to its maximum value, set the configuration, clear the
- // interrupt, then set the value.
- //
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerLoadValue, 0xFFFFFFFF);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerControl, ControlValue);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerInterruptClear, 1);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerLoadValue, TickCount);
- return;
- }
- VOID
- EfipBcm2709TimerDisarm (
- PBCM2709_TIMER Timer
- )
- /*++
- Routine Description:
- This routine disarms the timer, stopping interrupts from firing.
- Arguments:
- Timer - Supplies the pointer to the timer data.
- Return Value:
- None.
- --*/
- {
- UINT32 ControlValue;
- if (Timer->ClockTimer == FALSE) {
- return;
- }
- //
- // Disable the timer by programming it with no interrupt generation.
- //
- ControlValue = READ_ARM_TIMER_REGISTER(Bcm2709ArmTimerControl);
- ControlValue &= ~BCM2709_ARM_TIMER_CONTROL_INTERRUPT_ENABLE;
- ControlValue |= (BCM2709_ARM_TIMER_CONTROL_ENABLED |
- BCM2709_ARM_TIMER_CONTROL_DIVIDE_BY_1 |
- BCM2709_ARM_TIMER_CONTROL_32_BIT);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerControl, ControlValue);
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerInterruptClear, 1);
- return;
- }
- VOID
- EfipBcm2709TimerAcknowledgeInterrupt (
- PBCM2709_TIMER Timer
- )
- /*++
- Routine Description:
- This routine performs any actions necessary upon reciept of a timer's
- interrupt. This may involve writing to an acknowledge register to re-enable
- the timer to fire again, or other hardware specific actions.
- Arguments:
- Timer - Supplies the pointer to the timer data.
- Return Value:
- None.
- --*/
- {
- if (Timer->ClockTimer == FALSE) {
- return;
- }
- WRITE_ARM_TIMER_REGISTER(Bcm2709ArmTimerInterruptClear, 1);
- return;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
|