hwtimer.c revision 231844
171867Smsmith 271867Smsmith/****************************************************************************** 371867Smsmith * 471867Smsmith * Name: hwtimer.c - ACPI Power Management Timer Interface 571867Smsmith * 671867Smsmith *****************************************************************************/ 771867Smsmith 8217365Sjkim/* 9229989Sjkim * Copyright (C) 2000 - 2012, 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 52231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 5371867Smsmith/****************************************************************************** 5471867Smsmith * 5571867Smsmith * FUNCTION: AcpiGetTimerResolution 5671867Smsmith * 57138287Smarks * PARAMETERS: Resolution - Where the resolution is returned 5871867Smsmith * 59138287Smarks * RETURN: Status and timer resolution 6071867Smsmith * 61138287Smarks * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits). 6271867Smsmith * 6371867Smsmith ******************************************************************************/ 6471867Smsmith 6571867SmsmithACPI_STATUS 6671867SmsmithAcpiGetTimerResolution ( 6771867Smsmith UINT32 *Resolution) 6871867Smsmith{ 69167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetTimerResolution); 7071867Smsmith 7177424Smsmith 7271867Smsmith if (!Resolution) 7371867Smsmith { 7471867Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 7571867Smsmith } 7671867Smsmith 77167802Sjkim if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0) 7871867Smsmith { 7971867Smsmith *Resolution = 24; 8071867Smsmith } 8171867Smsmith else 8271867Smsmith { 8371867Smsmith *Resolution = 32; 8471867Smsmith } 8571867Smsmith 8671867Smsmith return_ACPI_STATUS (AE_OK); 8771867Smsmith} 8871867Smsmith 89167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimerResolution) 9071867Smsmith 91167802Sjkim 9271867Smsmith/****************************************************************************** 9371867Smsmith * 9471867Smsmith * FUNCTION: AcpiGetTimer 9571867Smsmith * 96138287Smarks * PARAMETERS: Ticks - Where the timer value is returned 9771867Smsmith * 98151937Sjkim * RETURN: Status and current timer value (ticks) 9971867Smsmith * 100138287Smarks * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks). 10171867Smsmith * 10271867Smsmith ******************************************************************************/ 10371867Smsmith 10471867SmsmithACPI_STATUS 10571867SmsmithAcpiGetTimer ( 10671867Smsmith UINT32 *Ticks) 10771867Smsmith{ 10899679Siwasaki ACPI_STATUS Status; 10999679Siwasaki 11099679Siwasaki 111167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetTimer); 11271867Smsmith 11383174Smsmith 11471867Smsmith if (!Ticks) 11571867Smsmith { 11671867Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 11771867Smsmith } 11871867Smsmith 119197104Sjkim Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock); 12071867Smsmith 12199679Siwasaki return_ACPI_STATUS (Status); 12271867Smsmith} 12371867Smsmith 124167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimer) 12571867Smsmith 126167802Sjkim 12771867Smsmith/****************************************************************************** 12871867Smsmith * 12971867Smsmith * FUNCTION: AcpiGetTimerDuration 13071867Smsmith * 131138287Smarks * PARAMETERS: StartTicks - Starting timestamp 132138287Smarks * EndTicks - End timestamp 133138287Smarks * TimeElapsed - Where the elapsed time is returned 13471867Smsmith * 135138287Smarks * RETURN: Status and TimeElapsed 13671867Smsmith * 13771867Smsmith * DESCRIPTION: Computes the time elapsed (in microseconds) between two 13871867Smsmith * PM Timer time stamps, taking into account the possibility of 13977424Smsmith * rollovers, the timer resolution, and timer frequency. 14077424Smsmith * 14177424Smsmith * The PM Timer's clock ticks at roughly 3.6 times per 14271867Smsmith * _microsecond_, and its clock continues through Cx state 14371867Smsmith * transitions (unlike many CPU timestamp counters) -- making it 14471867Smsmith * a versatile and accurate timer. 14571867Smsmith * 146114237Snjl * Note that this function accommodates only a single timer 14771867Smsmith * rollover. Thus for 24-bit timers, this function should only 14877424Smsmith * be used for calculating durations less than ~4.6 seconds 149138287Smarks * (~20 minutes for 32-bit timers) -- calculations below: 15071867Smsmith * 151114237Snjl * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec 152114237Snjl * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes 153114237Snjl * 15471867Smsmith ******************************************************************************/ 15571867Smsmith 15671867SmsmithACPI_STATUS 15771867SmsmithAcpiGetTimerDuration ( 15871867Smsmith UINT32 StartTicks, 15971867Smsmith UINT32 EndTicks, 16071867Smsmith UINT32 *TimeElapsed) 16171867Smsmith{ 16291116Smsmith ACPI_STATUS Status; 163138287Smarks UINT32 DeltaTicks; 164202771Sjkim UINT64 Quotient; 16571867Smsmith 16678986Smsmith 167167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetTimerDuration); 16871867Smsmith 16980062Smsmith 17077424Smsmith if (!TimeElapsed) 17171867Smsmith { 17271867Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 17371867Smsmith } 17471867Smsmith 17577424Smsmith /* 17671867Smsmith * Compute Tick Delta: 177138287Smarks * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. 17871867Smsmith */ 17971867Smsmith if (StartTicks < EndTicks) 18071867Smsmith { 18171867Smsmith DeltaTicks = EndTicks - StartTicks; 18271867Smsmith } 18377424Smsmith else if (StartTicks > EndTicks) 18471867Smsmith { 185167802Sjkim if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0) 18671867Smsmith { 18791116Smsmith /* 24-bit Timer */ 18891116Smsmith 18973561Smsmith DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF); 19071867Smsmith } 19177424Smsmith else 19271867Smsmith { 19391116Smsmith /* 32-bit Timer */ 19491116Smsmith 19571867Smsmith DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks; 19671867Smsmith } 19771867Smsmith } 198138287Smarks else /* StartTicks == EndTicks */ 19973561Smsmith { 20073561Smsmith *TimeElapsed = 0; 20173561Smsmith return_ACPI_STATUS (AE_OK); 20273561Smsmith } 20371867Smsmith 20477424Smsmith /* 205138287Smarks * Compute Duration (Requires a 64-bit multiply and divide): 20671867Smsmith * 20791116Smsmith * TimeElapsed = (DeltaTicks * 1000000) / PM_TIMER_FREQUENCY; 20871867Smsmith */ 209138287Smarks Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * 1000000, 210138287Smarks PM_TIMER_FREQUENCY, &Quotient, NULL); 21171867Smsmith 212138287Smarks *TimeElapsed = (UINT32) Quotient; 21391116Smsmith return_ACPI_STATUS (Status); 21471867Smsmith} 21571867Smsmith 216167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTimerDuration) 21771867Smsmith 218231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 219