brintos

brintos / linux-shallow public Read only

0
0
Text · 4.8 KiB · 192c04b Raw
176 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Name: hwtimer.c - ACPI Power Management Timer Interface5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#define EXPORT_ACPI_INTERFACES11 12#include <acpi/acpi.h>13#include "accommon.h"14 15#define _COMPONENT          ACPI_HARDWARE16ACPI_MODULE_NAME("hwtimer")17 18#if (!ACPI_REDUCED_HARDWARE)	/* Entire module */19/******************************************************************************20 *21 * FUNCTION:    acpi_get_timer_resolution22 *23 * PARAMETERS:  resolution          - Where the resolution is returned24 *25 * RETURN:      Status and timer resolution26 *27 * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).28 *29 ******************************************************************************/30acpi_status acpi_get_timer_resolution(u32 * resolution)31{32	ACPI_FUNCTION_TRACE(acpi_get_timer_resolution);33 34	if (!resolution) {35		return_ACPI_STATUS(AE_BAD_PARAMETER);36	}37 38	if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {39		*resolution = 24;40	} else {41		*resolution = 32;42	}43 44	return_ACPI_STATUS(AE_OK);45}46 47ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution)48 49/******************************************************************************50 *51 * FUNCTION:    acpi_get_timer52 *53 * PARAMETERS:  ticks               - Where the timer value is returned54 *55 * RETURN:      Status and current timer value (ticks)56 *57 * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).58 *59 ******************************************************************************/60acpi_status acpi_get_timer(u32 * ticks)61{62	acpi_status status;63	u64 timer_value;64 65	ACPI_FUNCTION_TRACE(acpi_get_timer);66 67	if (!ticks) {68		return_ACPI_STATUS(AE_BAD_PARAMETER);69	}70 71	/* ACPI 5.0A: PM Timer is optional */72 73	if (!acpi_gbl_FADT.xpm_timer_block.address) {74		return_ACPI_STATUS(AE_SUPPORT);75	}76 77	status = acpi_hw_read(&timer_value, &acpi_gbl_FADT.xpm_timer_block);78	if (ACPI_SUCCESS(status)) {79 80		/* ACPI PM Timer is defined to be 32 bits (PM_TMR_LEN) */81 82		*ticks = (u32)timer_value;83	}84 85	return_ACPI_STATUS(status);86}87 88ACPI_EXPORT_SYMBOL(acpi_get_timer)89 90/******************************************************************************91 *92 * FUNCTION:    acpi_get_timer_duration93 *94 * PARAMETERS:  start_ticks         - Starting timestamp95 *              end_ticks           - End timestamp96 *              time_elapsed        - Where the elapsed time is returned97 *98 * RETURN:      Status and time_elapsed99 *100 * DESCRIPTION: Computes the time elapsed (in microseconds) between two101 *              PM Timer time stamps, taking into account the possibility of102 *              rollovers, the timer resolution, and timer frequency.103 *104 *              The PM Timer's clock ticks at roughly 3.6 times per105 *              _microsecond_, and its clock continues through Cx state106 *              transitions (unlike many CPU timestamp counters) -- making it107 *              a versatile and accurate timer.108 *109 *              Note that this function accommodates only a single timer110 *              rollover. Thus for 24-bit timers, this function should only111 *              be used for calculating durations less than ~4.6 seconds112 *              (~20 minutes for 32-bit timers) -- calculations below:113 *114 *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec115 *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes116 *117 ******************************************************************************/118acpi_status119acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 *time_elapsed)120{121	acpi_status status;122	u64 delta_ticks;123	u64 quotient;124 125	ACPI_FUNCTION_TRACE(acpi_get_timer_duration);126 127	if (!time_elapsed) {128		return_ACPI_STATUS(AE_BAD_PARAMETER);129	}130 131	/* ACPI 5.0A: PM Timer is optional */132 133	if (!acpi_gbl_FADT.xpm_timer_block.address) {134		return_ACPI_STATUS(AE_SUPPORT);135	}136 137	if (start_ticks == end_ticks) {138		*time_elapsed = 0;139		return_ACPI_STATUS(AE_OK);140	}141 142	/*143	 * Compute Tick Delta:144	 * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.145	 */146	delta_ticks = end_ticks;147	if (start_ticks > end_ticks) {148		if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {149 150			/* 24-bit Timer */151 152			delta_ticks |= (u64)1 << 24;153		} else {154			/* 32-bit Timer */155 156			delta_ticks |= (u64)1 << 32;157		}158	}159	delta_ticks -= start_ticks;160 161	/*162	 * Compute Duration (Requires a 64-bit multiply and divide):163	 *164	 * time_elapsed (microseconds) =165	 *  (delta_ticks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;166	 */167	status = acpi_ut_short_divide(delta_ticks * ACPI_USEC_PER_SEC,168				      ACPI_PM_TIMER_FREQUENCY, &quotient, NULL);169 170	*time_elapsed = (u32)quotient;171	return_ACPI_STATUS(status);172}173 174ACPI_EXPORT_SYMBOL(acpi_get_timer_duration)175#endif				/* !ACPI_REDUCED_HARDWARE */176