xref: /illumos-gate/usr/src/uts/i86pc/os/cpupm/cpupm_intel.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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