hwtimer.c revision 253690
171867Smsmith/******************************************************************************
271867Smsmith *
371867Smsmith * Name: hwtimer.c - ACPI Power Management Timer Interface
471867Smsmith *
571867Smsmith *****************************************************************************/
671867Smsmith
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
971867Smsmith * All rights reserved.
1071867Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2571867Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2971867Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4371867Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
4671867Smsmith
4777424Smsmith#define _COMPONENT          ACPI_HARDWARE
4891116Smsmith        ACPI_MODULE_NAME    ("hwtimer")
4971867Smsmith
5071867Smsmith
51231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
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
118253690Sjkim    /* ACPI 5.0A: PM Timer is optional */
119253690Sjkim
120253690Sjkim    if (!AcpiGbl_FADT.XPmTimerBlock.Address)
121253690Sjkim    {
122253690Sjkim        return_ACPI_STATUS (AE_SUPPORT);
123253690Sjkim    }
124253690Sjkim
125197104Sjkim    Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock);
12699679Siwasaki    return_ACPI_STATUS (Status);
12771867Smsmith}
12871867Smsmith
129167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimer)
13071867Smsmith
131167802Sjkim
13271867Smsmith/******************************************************************************
13371867Smsmith *
13471867Smsmith * FUNCTION:    AcpiGetTimerDuration
13571867Smsmith *
136138287Smarks * PARAMETERS:  StartTicks          - Starting timestamp
137138287Smarks *              EndTicks            - End timestamp
138138287Smarks *              TimeElapsed         - Where the elapsed time is returned
13971867Smsmith *
140138287Smarks * RETURN:      Status and TimeElapsed
14171867Smsmith *
14271867Smsmith * DESCRIPTION: Computes the time elapsed (in microseconds) between two
14371867Smsmith *              PM Timer time stamps, taking into account the possibility of
14477424Smsmith *              rollovers, the timer resolution, and timer frequency.
14577424Smsmith *
14677424Smsmith *              The PM Timer's clock ticks at roughly 3.6 times per
14771867Smsmith *              _microsecond_, and its clock continues through Cx state
14871867Smsmith *              transitions (unlike many CPU timestamp counters) -- making it
14971867Smsmith *              a versatile and accurate timer.
15071867Smsmith *
151114237Snjl *              Note that this function accommodates only a single timer
152241973Sjkim *              rollover. Thus for 24-bit timers, this function should only
15377424Smsmith *              be used for calculating durations less than ~4.6 seconds
154138287Smarks *              (~20 minutes for 32-bit timers) -- calculations below:
15571867Smsmith *
156114237Snjl *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
157114237Snjl *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
158114237Snjl *
15971867Smsmith ******************************************************************************/
16071867Smsmith
16171867SmsmithACPI_STATUS
16271867SmsmithAcpiGetTimerDuration (
16371867Smsmith    UINT32                  StartTicks,
16471867Smsmith    UINT32                  EndTicks,
16571867Smsmith    UINT32                  *TimeElapsed)
16671867Smsmith{
16791116Smsmith    ACPI_STATUS             Status;
168138287Smarks    UINT32                  DeltaTicks;
169202771Sjkim    UINT64                  Quotient;
17071867Smsmith
17178986Smsmith
172167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetTimerDuration);
17371867Smsmith
17480062Smsmith
17577424Smsmith    if (!TimeElapsed)
17671867Smsmith    {
17771867Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
17871867Smsmith    }
17971867Smsmith
180253690Sjkim    /* ACPI 5.0A: PM Timer is optional */
181253690Sjkim
182253690Sjkim    if (!AcpiGbl_FADT.XPmTimerBlock.Address)
183253690Sjkim    {
184253690Sjkim        return_ACPI_STATUS (AE_SUPPORT);
185253690Sjkim    }
186253690Sjkim
18777424Smsmith    /*
18871867Smsmith     * Compute Tick Delta:
189138287Smarks     * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
19071867Smsmith     */
19171867Smsmith    if (StartTicks < EndTicks)
19271867Smsmith    {
19371867Smsmith        DeltaTicks = EndTicks - StartTicks;
19471867Smsmith    }
19577424Smsmith    else if (StartTicks > EndTicks)
19671867Smsmith    {
197167802Sjkim        if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
19871867Smsmith        {
19991116Smsmith            /* 24-bit Timer */
20091116Smsmith
20173561Smsmith            DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF);
20271867Smsmith        }
20377424Smsmith        else
20471867Smsmith        {
20591116Smsmith            /* 32-bit Timer */
20691116Smsmith
20771867Smsmith            DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks;
20871867Smsmith        }
20971867Smsmith    }
210138287Smarks    else /* StartTicks == EndTicks */
21173561Smsmith    {
21273561Smsmith        *TimeElapsed = 0;
21373561Smsmith        return_ACPI_STATUS (AE_OK);
21473561Smsmith    }
21571867Smsmith
21677424Smsmith    /*
217138287Smarks     * Compute Duration (Requires a 64-bit multiply and divide):
21871867Smsmith     *
219245582Sjkim     * TimeElapsed (microseconds) =
220245582Sjkim     *  (DeltaTicks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
22171867Smsmith     */
222245582Sjkim    Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * ACPI_USEC_PER_SEC,
223245582Sjkim                ACPI_PM_TIMER_FREQUENCY, &Quotient, NULL);
22471867Smsmith
225138287Smarks    *TimeElapsed = (UINT32) Quotient;
22691116Smsmith    return_ACPI_STATUS (Status);
22771867Smsmith}
22871867Smsmith
229167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimerDuration)
23071867Smsmith
231231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */
232