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