diff options
author | njl <njl@FreeBSD.org> | 2005-02-06 21:10:19 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2005-02-06 21:10:19 +0000 |
commit | 434b0e32d37c93824a31a6f3a0356a3e9f705afd (patch) | |
tree | 918539c868c8451ac633b6230566daa516ef43da /sys/dev/acpica | |
parent | 912fc2a19745b5907697fbde9678f5133f254c60 (diff) | |
download | FreeBSD-src-434b0e32d37c93824a31a6f3a0356a3e9f705afd.zip FreeBSD-src-434b0e32d37c93824a31a6f3a0356a3e9f705afd.tar.gz |
Remove acpi throttling support from the acpi_cpu(4) driver now that this
is supported by acpi_throttle(4).
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r-- | sys/dev/acpica/acpi_cpu.c | 245 |
1 files changed, 9 insertions, 236 deletions
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 7780ed7..f1b97fe 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -50,8 +50,7 @@ __FBSDID("$FreeBSD$"); #include <dev/acpica/acpivar.h> /* - * Support for ACPI Processor devices, including ACPI 2.0 throttling - * and C[1-3] sleep states. + * Support for ACPI Processor devices, including C[1-3] sleep states. * * TODO: implement scans of all CPUs to be sure all Cx states are * equivalent. @@ -77,8 +76,6 @@ struct acpi_cpu_softc { uint32_t cpu_acpi_id; /* ACPI processor id */ uint32_t cpu_p_blk; /* ACPI P_BLK location */ uint32_t cpu_p_blk_len; /* P_BLK length (must be 6). */ - struct resource *cpu_p_cnt; /* Throttling control register */ - int cpu_p_type; /* Resource type for cpu_p_cnt. */ struct acpi_cx cpu_cx_states[MAX_CX_STATES]; int cpu_cx_count; /* Number of valid Cx states. */ int cpu_prev_sleep;/* Last idle sleep duration. */ @@ -95,24 +92,12 @@ struct acpi_cpu_device { (bus_space_write_ ## width(rman_get_bustag((reg)), \ rman_get_bushandle((reg)), 0, (val))) -/* - * Speeds are stored in counts, from 1 to CPU_MAX_SPEED, and - * reported to the user in tenths of a percent. - */ -static uint32_t cpu_duty_offset; -static uint32_t cpu_duty_width; -#define CPU_MAX_SPEED (1 << cpu_duty_width) -#define CPU_SPEED_PERCENT(x) ((1000 * (x)) / CPU_MAX_SPEED) -#define CPU_SPEED_PRINTABLE(x) (CPU_SPEED_PERCENT(x) / 10), \ - (CPU_SPEED_PERCENT(x) % 10) -#define CPU_P_CNT_THT_EN (1<<4) #define PM_USEC(x) ((x) >> 2) /* ~4 clocks per usec (3.57955 Mhz) */ #define ACPI_CPU_NOTIFY_PERF_STATES 0x80 /* _PSS changed. */ #define ACPI_CPU_NOTIFY_CX_STATES 0x81 /* _CST changed. */ #define CPU_QUIRK_NO_C3 (1<<0) /* C3-type states are not usable. */ -#define CPU_QUIRK_NO_THROTTLE (1<<1) /* Throttling is not usable. */ #define CPU_QUIRK_NO_BM_CTRL (1<<2) /* No bus mastering control. */ #define PCI_VENDOR_INTEL 0x8086 @@ -136,8 +121,6 @@ static u_int cpu_cx_stats[MAX_CX_STATES];/* Cx usage history. */ /* Values for sysctl. */ static struct sysctl_ctx_list acpi_cpu_sysctl_ctx; static struct sysctl_oid *acpi_cpu_sysctl_tree; -static uint32_t cpu_throttle_state; -static uint32_t cpu_throttle_max; static int cpu_cx_lowest; static char cpu_cx_supported[64]; @@ -156,17 +139,13 @@ static device_t acpi_cpu_add_child(device_t dev, int order, const char *name, static int acpi_cpu_read_ivar(device_t dev, device_t child, int index, uintptr_t *result); static int acpi_cpu_shutdown(device_t dev); -static int acpi_cpu_throttle_probe(struct acpi_cpu_softc *sc); static int acpi_cpu_cx_probe(struct acpi_cpu_softc *sc); static int acpi_cpu_cx_cst(struct acpi_cpu_softc *sc); static void acpi_cpu_startup(void *arg); -static void acpi_cpu_startup_throttling(void); static void acpi_cpu_startup_cx(void); -static void acpi_cpu_throttle_set(uint32_t speed); static void acpi_cpu_idle(void); static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context); static int acpi_cpu_quirks(struct acpi_cpu_softc *sc); -static int acpi_cpu_throttle_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); @@ -297,7 +276,7 @@ acpi_cpu_attach(device_t dev) struct acpi_cpu_softc *sc; struct acpi_softc *acpi_sc; ACPI_STATUS status; - int cx_ret, cpu_id, thr_ret; + int cpu_id; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); @@ -309,6 +288,8 @@ acpi_cpu_attach(device_t dev) pcpu_data = pcpu_find(cpu_id); pcpu_data->pc_device = dev; sc->cpu_pcpu = pcpu_data; + cpu_smi_cmd = AcpiGbl_FADT->SmiCmd; + cpu_cst_cnt = AcpiGbl_FADT->CstCnt; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; @@ -333,19 +314,16 @@ acpi_cpu_attach(device_t dev) CTLFLAG_RD, 0, ""); /* - * Probe for throttling and Cx state support. - * If none of these is present, free up unused resources. + * Probe for Cx state support. If it isn't present, free up unused + * resources. */ - thr_ret = acpi_cpu_throttle_probe(sc); - cx_ret = acpi_cpu_cx_probe(sc); - if (thr_ret == 0 || cx_ret == 0) { + if (acpi_cpu_cx_probe(sc) == 0) { status = AcpiInstallNotifyHandler(sc->cpu_handle, ACPI_DEVICE_NOTIFY, acpi_cpu_notify, sc); if (device_get_unit(dev) == 0) AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cpu_startup, NULL); - } else { + } else sysctl_ctx_free(&acpi_cpu_sysctl_ctx); - } /* Call identify and then probe/attach for cpu child drivers. */ bus_generic_probe(dev); @@ -455,89 +433,6 @@ acpi_cpu_shutdown(device_t dev) } static int -acpi_cpu_throttle_probe(struct acpi_cpu_softc *sc) -{ - uint32_t duty_end; - ACPI_BUFFER buf; - ACPI_OBJECT obj; - ACPI_GENERIC_ADDRESS gas; - ACPI_STATUS status; - - ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - - /* Get throttling parameters from the FADT. 0 means not supported. */ - if (device_get_unit(sc->cpu_dev) == 0) { - cpu_smi_cmd = AcpiGbl_FADT->SmiCmd; - cpu_cst_cnt = AcpiGbl_FADT->CstCnt; - cpu_duty_offset = AcpiGbl_FADT->DutyOffset; - cpu_duty_width = AcpiGbl_FADT->DutyWidth; - } - if (cpu_duty_width == 0 || (cpu_quirks & CPU_QUIRK_NO_THROTTLE) != 0) - return (ENXIO); - - /* Validate the duty offset/width. */ - duty_end = cpu_duty_offset + cpu_duty_width - 1; - if (duty_end > 31) { - device_printf(sc->cpu_dev, "CLK_VAL field overflows P_CNT register\n"); - return (ENXIO); - } - if (cpu_duty_offset <= 4 && duty_end >= 4) { - device_printf(sc->cpu_dev, "CLK_VAL field overlaps THT_EN bit\n"); - return (ENXIO); - } - - /* - * If not present, fall back to using the processor's P_BLK to find - * the P_CNT register. - * - * Note that some systems seem to duplicate the P_BLK pointer - * across multiple CPUs, so not getting the resource is not fatal. - */ - buf.Pointer = &obj; - buf.Length = sizeof(obj); - status = AcpiEvaluateObject(sc->cpu_handle, "_PTC", NULL, &buf); - if (ACPI_SUCCESS(status)) { - if (obj.Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3) { - device_printf(sc->cpu_dev, "_PTC buffer too small\n"); - return (ENXIO); - } - memcpy(&gas, obj.Buffer.Pointer + 3, sizeof(gas)); - acpi_bus_alloc_gas(sc->cpu_dev, &sc->cpu_p_type, &cpu_rid, &gas, - &sc->cpu_p_cnt); - if (sc->cpu_p_cnt != NULL) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_CNT from _PTC\n", - device_get_unit(sc->cpu_dev))); - } - } - - /* If _PTC not present or other failure, try the P_BLK. */ - if (sc->cpu_p_cnt == NULL) { - /* - * The spec says P_BLK must be 6 bytes long. However, some - * systems use it to indicate a fractional set of features - * present so we take anything >= 4. - */ - if (sc->cpu_p_blk_len < 4) - return (ENXIO); - gas.Address = sc->cpu_p_blk; - gas.AddressSpaceId = ACPI_ADR_SPACE_SYSTEM_IO; - gas.RegisterBitWidth = 32; - acpi_bus_alloc_gas(sc->cpu_dev, &sc->cpu_p_type, &cpu_rid, &gas, - &sc->cpu_p_cnt); - if (sc->cpu_p_cnt != NULL) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_CNT from P_BLK\n", - device_get_unit(sc->cpu_dev))); - } else { - device_printf(sc->cpu_dev, "Failed to attach throttling P_CNT\n"); - return (ENXIO); - } - } - cpu_rid++; - - return (0); -} - -static int acpi_cpu_cx_probe(struct acpi_cpu_softc *sc) { ACPI_GENERIC_ADDRESS gas; @@ -776,50 +671,12 @@ acpi_cpu_startup(void *arg) } cpu_cx_count = count; - /* Perform throttling and Cx final initialization. */ + /* Perform Cx final initialization. */ sc = device_get_softc(cpu_devices[0]); - if (sc->cpu_p_cnt != NULL) - acpi_cpu_startup_throttling(); if (cpu_cx_count > 0) acpi_cpu_startup_cx(); } -/* - * Takes the ACPI lock to avoid fighting anyone over the SMI command - * port. - */ -static void -acpi_cpu_startup_throttling() -{ - - /* If throttling is not usable, don't initialize it. */ - if (cpu_quirks & CPU_QUIRK_NO_THROTTLE) - return; - - /* Initialise throttling states */ - cpu_throttle_max = CPU_MAX_SPEED; - cpu_throttle_state = CPU_MAX_SPEED; - - SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx, - SYSCTL_CHILDREN(acpi_cpu_sysctl_tree), - OID_AUTO, "throttle_max", CTLFLAG_RD, - &cpu_throttle_max, 0, "maximum CPU speed"); - SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx, - SYSCTL_CHILDREN(acpi_cpu_sysctl_tree), - OID_AUTO, "throttle_state", - CTLTYPE_INT | CTLFLAG_RW, &cpu_throttle_state, - 0, acpi_cpu_throttle_sysctl, "I", "current CPU speed"); - - /* Set initial speed to maximum. */ - ACPI_SERIAL_BEGIN(cpu); - acpi_cpu_throttle_set(cpu_throttle_max); - ACPI_SERIAL_END(cpu); - - printf("acpi_cpu: throttling enabled, %d steps (100%% to %d.%d%%), " - "currently %d.%d%%\n", CPU_MAX_SPEED, CPU_SPEED_PRINTABLE(1), - CPU_SPEED_PRINTABLE(cpu_throttle_state)); -} - static void acpi_cpu_startup_cx() { @@ -871,49 +728,6 @@ acpi_cpu_startup_cx() } /* - * Set CPUs to the new state. - * - * Must be called with the ACPI lock held. - */ -static void -acpi_cpu_throttle_set(uint32_t speed) -{ - struct acpi_cpu_softc *sc; - int i; - uint32_t p_cnt, clk_val; - - ACPI_SERIAL_ASSERT(cpu); - - /* Iterate over processors */ - for (i = 0; i < cpu_ndevices; i++) { - sc = device_get_softc(cpu_devices[i]); - if (sc->cpu_p_cnt == NULL) - continue; - - /* Get the current P_CNT value and disable throttling */ - p_cnt = CPU_GET_REG(sc->cpu_p_cnt, 4); - p_cnt &= ~CPU_P_CNT_THT_EN; - CPU_SET_REG(sc->cpu_p_cnt, 4, p_cnt); - - /* If we're at maximum speed, that's all */ - if (speed < CPU_MAX_SPEED) { - /* Mask the old CLK_VAL off and or-in the new value */ - clk_val = (CPU_MAX_SPEED - 1) << cpu_duty_offset; - p_cnt &= ~clk_val; - p_cnt |= (speed << cpu_duty_offset); - - /* Write the new P_CNT value and then enable throttling */ - CPU_SET_REG(sc->cpu_p_cnt, 4, p_cnt); - p_cnt |= CPU_P_CNT_THT_EN; - CPU_SET_REG(sc->cpu_p_cnt, 4, p_cnt); - } - ACPI_VPRINT(sc->cpu_dev, acpi_device_get_parent_softc(sc->cpu_dev), - "set speed to %d.%d%%\n", CPU_SPEED_PRINTABLE(speed)); - } - cpu_throttle_state = speed; -} - -/* * Idle the CPU in the lowest state possible. This function is called with * interrupts disabled. Note that once it re-enables interrupts, a task * switch can occur so do not access shared data (i.e. the softc) after @@ -1076,18 +890,6 @@ acpi_cpu_quirks(struct acpi_cpu_softc *sc) if (acpi_dev != NULL) { switch (pci_get_revid(acpi_dev)) { /* - * Disable throttling control on PIIX4 A and B-step. - * See specification changes #13 ("Manual Throttle Duty Cycle") - * and #14 ("Enabling and Disabling Manual Throttle"), plus - * erratum #5 ("STPCLK# Deassertion Time") from the January - * 2002 PIIX4 specification update. Note that few (if any) - * mobile systems ever used this part. - */ - case PCI_REVISION_A_STEP: - case PCI_REVISION_B_STEP: - cpu_quirks |= CPU_QUIRK_NO_THROTTLE; - /* FALLTHROUGH */ - /* * Disable C3 support for all PIIX4 chipsets. Some of these parts * do not report the BMIDE status to the BM status register and * others have a livelock bug if Type-F DMA is enabled. Linux @@ -1111,35 +913,6 @@ acpi_cpu_quirks(struct acpi_cpu_softc *sc) return (0); } -/* Handle changes in the CPU throttling setting. */ -static int -acpi_cpu_throttle_sysctl(SYSCTL_HANDLER_ARGS) -{ - uint32_t *argp; - uint32_t arg; - int error; - - argp = (uint32_t *)oidp->oid_arg1; - arg = *argp; - error = sysctl_handle_int(oidp, &arg, 0, req); - - /* Error or no new value */ - if (error != 0 || req->newptr == NULL) - return (error); - if (arg < 1 || arg > cpu_throttle_max) - return (EINVAL); - - /* If throttling changed, notify the BIOS of the new rate. */ - ACPI_SERIAL_BEGIN(cpu); - if (*argp != arg) { - *argp = arg; - acpi_cpu_throttle_set(arg); - } - ACPI_SERIAL_END(cpu); - - return (0); -} - static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS) { |