hwtimer.c revision 231844
1 2/****************************************************************************** 3 * 4 * Name: hwtimer.c - ACPI Power Management Timer Interface 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/include/acpi.h> 46#include <contrib/dev/acpica/include/accommon.h> 47 48#define _COMPONENT ACPI_HARDWARE 49 ACPI_MODULE_NAME ("hwtimer") 50 51 52#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 53/****************************************************************************** 54 * 55 * FUNCTION: AcpiGetTimerResolution 56 * 57 * PARAMETERS: Resolution - Where the resolution is returned 58 * 59 * RETURN: Status and timer resolution 60 * 61 * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits). 62 * 63 ******************************************************************************/ 64 65ACPI_STATUS 66AcpiGetTimerResolution ( 67 UINT32 *Resolution) 68{ 69 ACPI_FUNCTION_TRACE (AcpiGetTimerResolution); 70 71 72 if (!Resolution) 73 { 74 return_ACPI_STATUS (AE_BAD_PARAMETER); 75 } 76 77 if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0) 78 { 79 *Resolution = 24; 80 } 81 else 82 { 83 *Resolution = 32; 84 } 85 86 return_ACPI_STATUS (AE_OK); 87} 88 89ACPI_EXPORT_SYMBOL (AcpiGetTimerResolution) 90 91 92/****************************************************************************** 93 * 94 * FUNCTION: AcpiGetTimer 95 * 96 * PARAMETERS: Ticks - Where the timer value is returned 97 * 98 * RETURN: Status and current timer value (ticks) 99 * 100 * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks). 101 * 102 ******************************************************************************/ 103 104ACPI_STATUS 105AcpiGetTimer ( 106 UINT32 *Ticks) 107{ 108 ACPI_STATUS Status; 109 110 111 ACPI_FUNCTION_TRACE (AcpiGetTimer); 112 113 114 if (!Ticks) 115 { 116 return_ACPI_STATUS (AE_BAD_PARAMETER); 117 } 118 119 Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock); 120 121 return_ACPI_STATUS (Status); 122} 123 124ACPI_EXPORT_SYMBOL (AcpiGetTimer) 125 126 127/****************************************************************************** 128 * 129 * FUNCTION: AcpiGetTimerDuration 130 * 131 * PARAMETERS: StartTicks - Starting timestamp 132 * EndTicks - End timestamp 133 * TimeElapsed - Where the elapsed time is returned 134 * 135 * RETURN: Status and TimeElapsed 136 * 137 * DESCRIPTION: Computes the time elapsed (in microseconds) between two 138 * PM Timer time stamps, taking into account the possibility of 139 * rollovers, the timer resolution, and timer frequency. 140 * 141 * The PM Timer's clock ticks at roughly 3.6 times per 142 * _microsecond_, and its clock continues through Cx state 143 * transitions (unlike many CPU timestamp counters) -- making it 144 * a versatile and accurate timer. 145 * 146 * Note that this function accommodates only a single timer 147 * rollover. Thus for 24-bit timers, this function should only 148 * be used for calculating durations less than ~4.6 seconds 149 * (~20 minutes for 32-bit timers) -- calculations below: 150 * 151 * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec 152 * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes 153 * 154 ******************************************************************************/ 155 156ACPI_STATUS 157AcpiGetTimerDuration ( 158 UINT32 StartTicks, 159 UINT32 EndTicks, 160 UINT32 *TimeElapsed) 161{ 162 ACPI_STATUS Status; 163 UINT32 DeltaTicks; 164 UINT64 Quotient; 165 166 167 ACPI_FUNCTION_TRACE (AcpiGetTimerDuration); 168 169 170 if (!TimeElapsed) 171 { 172 return_ACPI_STATUS (AE_BAD_PARAMETER); 173 } 174 175 /* 176 * Compute Tick Delta: 177 * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. 178 */ 179 if (StartTicks < EndTicks) 180 { 181 DeltaTicks = EndTicks - StartTicks; 182 } 183 else if (StartTicks > EndTicks) 184 { 185 if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0) 186 { 187 /* 24-bit Timer */ 188 189 DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF); 190 } 191 else 192 { 193 /* 32-bit Timer */ 194 195 DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks; 196 } 197 } 198 else /* StartTicks == EndTicks */ 199 { 200 *TimeElapsed = 0; 201 return_ACPI_STATUS (AE_OK); 202 } 203 204 /* 205 * Compute Duration (Requires a 64-bit multiply and divide): 206 * 207 * TimeElapsed = (DeltaTicks * 1000000) / PM_TIMER_FREQUENCY; 208 */ 209 Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * 1000000, 210 PM_TIMER_FREQUENCY, &Quotient, NULL); 211 212 *TimeElapsed = (UINT32) Quotient; 213 return_ACPI_STATUS (Status); 214} 215 216ACPI_EXPORT_SYMBOL (AcpiGetTimerDuration) 217 218#endif /* !ACPI_REDUCED_HARDWARE */ 219