Home | History | Annotate | Line # | Download | only in hardware
hwtimer.c revision 1.1.1.2
      1 
      2 /******************************************************************************
      3  *
      4  * Name: hwtimer.c - ACPI Power Management Timer Interface
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #include "acpi.h"
     46 #include "accommon.h"
     47 
     48 #define _COMPONENT          ACPI_HARDWARE
     49         ACPI_MODULE_NAME    ("hwtimer")
     50 
     51 
     52 /******************************************************************************
     53  *
     54  * FUNCTION:    AcpiGetTimerResolution
     55  *
     56  * PARAMETERS:  Resolution          - Where the resolution is returned
     57  *
     58  * RETURN:      Status and timer resolution
     59  *
     60  * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
     61  *
     62  ******************************************************************************/
     63 
     64 ACPI_STATUS
     65 AcpiGetTimerResolution (
     66     UINT32                  *Resolution)
     67 {
     68     ACPI_FUNCTION_TRACE (AcpiGetTimerResolution);
     69 
     70 
     71     if (!Resolution)
     72     {
     73         return_ACPI_STATUS (AE_BAD_PARAMETER);
     74     }
     75 
     76     if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
     77     {
     78         *Resolution = 24;
     79     }
     80     else
     81     {
     82         *Resolution = 32;
     83     }
     84 
     85     return_ACPI_STATUS (AE_OK);
     86 }
     87 
     88 ACPI_EXPORT_SYMBOL (AcpiGetTimerResolution)
     89 
     90 
     91 /******************************************************************************
     92  *
     93  * FUNCTION:    AcpiGetTimer
     94  *
     95  * PARAMETERS:  Ticks               - Where the timer value is returned
     96  *
     97  * RETURN:      Status and current timer value (ticks)
     98  *
     99  * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
    100  *
    101  ******************************************************************************/
    102 
    103 ACPI_STATUS
    104 AcpiGetTimer (
    105     UINT32                  *Ticks)
    106 {
    107     ACPI_STATUS             Status;
    108 
    109 
    110     ACPI_FUNCTION_TRACE (AcpiGetTimer);
    111 
    112 
    113     if (!Ticks)
    114     {
    115         return_ACPI_STATUS (AE_BAD_PARAMETER);
    116     }
    117 
    118     Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock);
    119 
    120     return_ACPI_STATUS (Status);
    121 }
    122 
    123 ACPI_EXPORT_SYMBOL (AcpiGetTimer)
    124 
    125 
    126 /******************************************************************************
    127  *
    128  * FUNCTION:    AcpiGetTimerDuration
    129  *
    130  * PARAMETERS:  StartTicks          - Starting timestamp
    131  *              EndTicks            - End timestamp
    132  *              TimeElapsed         - Where the elapsed time is returned
    133  *
    134  * RETURN:      Status and TimeElapsed
    135  *
    136  * DESCRIPTION: Computes the time elapsed (in microseconds) between two
    137  *              PM Timer time stamps, taking into account the possibility of
    138  *              rollovers, the timer resolution, and timer frequency.
    139  *
    140  *              The PM Timer's clock ticks at roughly 3.6 times per
    141  *              _microsecond_, and its clock continues through Cx state
    142  *              transitions (unlike many CPU timestamp counters) -- making it
    143  *              a versatile and accurate timer.
    144  *
    145  *              Note that this function accommodates only a single timer
    146  *              rollover.  Thus for 24-bit timers, this function should only
    147  *              be used for calculating durations less than ~4.6 seconds
    148  *              (~20 minutes for 32-bit timers) -- calculations below:
    149  *
    150  *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
    151  *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
    152  *
    153  ******************************************************************************/
    154 
    155 ACPI_STATUS
    156 AcpiGetTimerDuration (
    157     UINT32                  StartTicks,
    158     UINT32                  EndTicks,
    159     UINT32                  *TimeElapsed)
    160 {
    161     ACPI_STATUS             Status;
    162     UINT32                  DeltaTicks;
    163     UINT64                  Quotient;
    164 
    165 
    166     ACPI_FUNCTION_TRACE (AcpiGetTimerDuration);
    167 
    168 
    169     if (!TimeElapsed)
    170     {
    171         return_ACPI_STATUS (AE_BAD_PARAMETER);
    172     }
    173 
    174     /*
    175      * Compute Tick Delta:
    176      * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
    177      */
    178     if (StartTicks < EndTicks)
    179     {
    180         DeltaTicks = EndTicks - StartTicks;
    181     }
    182     else if (StartTicks > EndTicks)
    183     {
    184         if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
    185         {
    186             /* 24-bit Timer */
    187 
    188             DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF);
    189         }
    190         else
    191         {
    192             /* 32-bit Timer */
    193 
    194             DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks;
    195         }
    196     }
    197     else /* StartTicks == EndTicks */
    198     {
    199         *TimeElapsed = 0;
    200         return_ACPI_STATUS (AE_OK);
    201     }
    202 
    203     /*
    204      * Compute Duration (Requires a 64-bit multiply and divide):
    205      *
    206      * TimeElapsed = (DeltaTicks * 1000000) / PM_TIMER_FREQUENCY;
    207      */
    208     Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * 1000000,
    209                 PM_TIMER_FREQUENCY, &Quotient, NULL);
    210 
    211     *TimeElapsed = (UINT32) Quotient;
    212     return_ACPI_STATUS (Status);
    213 }
    214 
    215 ACPI_EXPORT_SYMBOL (AcpiGetTimerDuration)
    216 
    217