hwtimer.c revision 217365
171867Smsmith
271867Smsmith/******************************************************************************
371867Smsmith *
471867Smsmith * Name: hwtimer.c - ACPI Power Management Timer Interface
571867Smsmith *
671867Smsmith *****************************************************************************/
771867Smsmith
8217365Sjkim/*
9217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
1071867Smsmith * All rights reserved.
1171867Smsmith *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
2671867Smsmith *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
3071867Smsmith *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
4471867Smsmith
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
4771867Smsmith
4877424Smsmith#define _COMPONENT          ACPI_HARDWARE
4991116Smsmith        ACPI_MODULE_NAME    ("hwtimer")
5071867Smsmith
5171867Smsmith
5271867Smsmith/******************************************************************************
5371867Smsmith *
5471867Smsmith * FUNCTION:    AcpiGetTimerResolution
5571867Smsmith *
56138287Smarks * PARAMETERS:  Resolution          - Where the resolution is returned
5771867Smsmith *
58138287Smarks * RETURN:      Status and timer resolution
5971867Smsmith *
60138287Smarks * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
6171867Smsmith *
6271867Smsmith ******************************************************************************/
6371867Smsmith
6471867SmsmithACPI_STATUS
6571867SmsmithAcpiGetTimerResolution (
6671867Smsmith    UINT32                  *Resolution)
6771867Smsmith{
68167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetTimerResolution);
6971867Smsmith
7077424Smsmith
7171867Smsmith    if (!Resolution)
7271867Smsmith    {
7371867Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
7471867Smsmith    }
7571867Smsmith
76167802Sjkim    if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
7771867Smsmith    {
7871867Smsmith        *Resolution = 24;
7971867Smsmith    }
8071867Smsmith    else
8171867Smsmith    {
8271867Smsmith        *Resolution = 32;
8371867Smsmith    }
8471867Smsmith
8571867Smsmith    return_ACPI_STATUS (AE_OK);
8671867Smsmith}
8771867Smsmith
88167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimerResolution)
8971867Smsmith
90167802Sjkim
9171867Smsmith/******************************************************************************
9271867Smsmith *
9371867Smsmith * FUNCTION:    AcpiGetTimer
9471867Smsmith *
95138287Smarks * PARAMETERS:  Ticks               - Where the timer value is returned
9671867Smsmith *
97151937Sjkim * RETURN:      Status and current timer value (ticks)
9871867Smsmith *
99138287Smarks * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
10071867Smsmith *
10171867Smsmith ******************************************************************************/
10271867Smsmith
10371867SmsmithACPI_STATUS
10471867SmsmithAcpiGetTimer (
10571867Smsmith    UINT32                  *Ticks)
10671867Smsmith{
10799679Siwasaki    ACPI_STATUS             Status;
10899679Siwasaki
10999679Siwasaki
110167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetTimer);
11171867Smsmith
11283174Smsmith
11371867Smsmith    if (!Ticks)
11471867Smsmith    {
11571867Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
11671867Smsmith    }
11771867Smsmith
118197104Sjkim    Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock);
11971867Smsmith
12099679Siwasaki    return_ACPI_STATUS (Status);
12171867Smsmith}
12271867Smsmith
123167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimer)
12471867Smsmith
125167802Sjkim
12671867Smsmith/******************************************************************************
12771867Smsmith *
12871867Smsmith * FUNCTION:    AcpiGetTimerDuration
12971867Smsmith *
130138287Smarks * PARAMETERS:  StartTicks          - Starting timestamp
131138287Smarks *              EndTicks            - End timestamp
132138287Smarks *              TimeElapsed         - Where the elapsed time is returned
13371867Smsmith *
134138287Smarks * RETURN:      Status and TimeElapsed
13571867Smsmith *
13671867Smsmith * DESCRIPTION: Computes the time elapsed (in microseconds) between two
13771867Smsmith *              PM Timer time stamps, taking into account the possibility of
13877424Smsmith *              rollovers, the timer resolution, and timer frequency.
13977424Smsmith *
14077424Smsmith *              The PM Timer's clock ticks at roughly 3.6 times per
14171867Smsmith *              _microsecond_, and its clock continues through Cx state
14271867Smsmith *              transitions (unlike many CPU timestamp counters) -- making it
14371867Smsmith *              a versatile and accurate timer.
14471867Smsmith *
145114237Snjl *              Note that this function accommodates only a single timer
14671867Smsmith *              rollover.  Thus for 24-bit timers, this function should only
14777424Smsmith *              be used for calculating durations less than ~4.6 seconds
148138287Smarks *              (~20 minutes for 32-bit timers) -- calculations below:
14971867Smsmith *
150114237Snjl *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
151114237Snjl *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
152114237Snjl *
15371867Smsmith ******************************************************************************/
15471867Smsmith
15571867SmsmithACPI_STATUS
15671867SmsmithAcpiGetTimerDuration (
15771867Smsmith    UINT32                  StartTicks,
15871867Smsmith    UINT32                  EndTicks,
15971867Smsmith    UINT32                  *TimeElapsed)
16071867Smsmith{
16191116Smsmith    ACPI_STATUS             Status;
162138287Smarks    UINT32                  DeltaTicks;
163202771Sjkim    UINT64                  Quotient;
16471867Smsmith
16578986Smsmith
166167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetTimerDuration);
16771867Smsmith
16880062Smsmith
16977424Smsmith    if (!TimeElapsed)
17071867Smsmith    {
17171867Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
17271867Smsmith    }
17371867Smsmith
17477424Smsmith    /*
17571867Smsmith     * Compute Tick Delta:
176138287Smarks     * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
17771867Smsmith     */
17871867Smsmith    if (StartTicks < EndTicks)
17971867Smsmith    {
18071867Smsmith        DeltaTicks = EndTicks - StartTicks;
18171867Smsmith    }
18277424Smsmith    else if (StartTicks > EndTicks)
18371867Smsmith    {
184167802Sjkim        if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
18571867Smsmith        {
18691116Smsmith            /* 24-bit Timer */
18791116Smsmith
18873561Smsmith            DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF);
18971867Smsmith        }
19077424Smsmith        else
19171867Smsmith        {
19291116Smsmith            /* 32-bit Timer */
19391116Smsmith
19471867Smsmith            DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks;
19571867Smsmith        }
19671867Smsmith    }
197138287Smarks    else /* StartTicks == EndTicks */
19873561Smsmith    {
19973561Smsmith        *TimeElapsed = 0;
20073561Smsmith        return_ACPI_STATUS (AE_OK);
20173561Smsmith    }
20271867Smsmith
20377424Smsmith    /*
204138287Smarks     * Compute Duration (Requires a 64-bit multiply and divide):
20571867Smsmith     *
20691116Smsmith     * TimeElapsed = (DeltaTicks * 1000000) / PM_TIMER_FREQUENCY;
20771867Smsmith     */
208138287Smarks    Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * 1000000,
209138287Smarks                PM_TIMER_FREQUENCY, &Quotient, NULL);
21071867Smsmith
211138287Smarks    *TimeElapsed = (UINT32) Quotient;
21291116Smsmith    return_ACPI_STATUS (Status);
21371867Smsmith}
21471867Smsmith
215167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimerDuration)
21671867Smsmith
217