1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Intel specific CPU power management support. 28 */ 29 30 #include <sys/x86_archext.h> 31 #include <sys/cpu_acpi.h> 32 #include <sys/speedstep.h> 33 #include <sys/cpupm_throttle.h> 34 #include <sys/cpu_idle.h> 35 36 /* 37 * The Intel Processor Driver Capabilities (_PDC). 38 * See Intel Processor Vendor-Specific ACPI Interface Specification 39 * for details. 40 */ 41 #define CPUPM_INTEL_PDC_REVISION 0x1 42 #define CPUPM_INTEL_PDC_PS_MSR 0x0001 43 #define CPUPM_INTEL_PDC_C1_HALT 0x0002 44 #define CPUPM_INTEL_PDC_TS_MSR 0x0004 45 #define CPUPM_INTEL_PDC_MP 0x0008 46 #define CPUPM_INTEL_PDC_C2C3_MP 0x0010 47 #define CPUPM_INTEL_PDC_SW_PSD 0x0020 48 #define CPUPM_INTEL_PDC_TSD 0x0080 49 #define CPUPM_INTEL_PDC_C1_FFH 0x0100 50 #define CPUPM_INTEL_PDC_HW_PSD 0x0800 51 52 static uint32_t cpupm_intel_pdccap = 0; 53 54 boolean_t 55 cpupm_intel_init(cpu_t *cp) 56 { 57 cpupm_mach_state_t *mach_state = 58 (cpupm_mach_state_t *)(cp->cpu_m.mcpu_pm_mach_state); 59 uint_t family; 60 uint_t model; 61 62 if (x86_vendor != X86_VENDOR_Intel) 63 return (B_FALSE); 64 65 family = cpuid_getfamily(CPU); 66 model = cpuid_getmodel(CPU); 67 68 cpupm_intel_pdccap = CPUPM_INTEL_PDC_MP; 69 70 /* 71 * If we support SpeedStep on this processor, then set the 72 * correct cma_ops for the processor and enable appropriate 73 * _PDC bits. 74 */ 75 if (speedstep_supported(family, model)) { 76 mach_state->ms_pstate.cma_ops = &speedstep_ops; 77 cpupm_intel_pdccap |= CPUPM_INTEL_PDC_PS_MSR | 78 CPUPM_INTEL_PDC_C1_HALT | CPUPM_INTEL_PDC_SW_PSD | 79 CPUPM_INTEL_PDC_HW_PSD; 80 } else { 81 mach_state->ms_pstate.cma_ops = NULL; 82 } 83 84 /* 85 * Set the correct tstate_ops for the processor and 86 * enable appropriate _PDC bits. 87 */ 88 mach_state->ms_tstate.cma_ops = &cpupm_throttle_ops; 89 cpupm_intel_pdccap |= CPUPM_INTEL_PDC_TS_MSR | 90 CPUPM_INTEL_PDC_TSD; 91 92 /* 93 * If we support deep cstates on this processor, then set the 94 * correct cstate_ops for the processor and enable appropriate 95 * _PDC bits. 96 */ 97 mach_state->ms_cstate.cma_ops = &cpu_idle_ops; 98 cpupm_intel_pdccap |= CPUPM_INTEL_PDC_C1_HALT | 99 CPUPM_INTEL_PDC_C2C3_MP | CPUPM_INTEL_PDC_C1_FFH; 100 101 /* 102 * _PDC support is optional and the driver should 103 * function even if the _PDC write fails. 104 */ 105 (void) cpu_acpi_write_pdc(mach_state->ms_acpi_handle, 106 CPUPM_INTEL_PDC_REVISION, 1, &cpupm_intel_pdccap); 107 108 return (B_TRUE); 109 } 110