xref: /illumos-gate/usr/src/uts/i86pc/os/cpupm/cpupm_intel.c (revision a31148363f598def767ac48c5d82e1572e44b935)
10e751525SEric Saxe /*
20e751525SEric Saxe  * CDDL HEADER START
30e751525SEric Saxe  *
40e751525SEric Saxe  * The contents of this file are subject to the terms of the
50e751525SEric Saxe  * Common Development and Distribution License (the "License").
60e751525SEric Saxe  * You may not use this file except in compliance with the License.
70e751525SEric Saxe  *
80e751525SEric Saxe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90e751525SEric Saxe  * or http://www.opensolaris.org/os/licensing.
100e751525SEric Saxe  * See the License for the specific language governing permissions
110e751525SEric Saxe  * and limitations under the License.
120e751525SEric Saxe  *
130e751525SEric Saxe  * When distributing Covered Code, include this CDDL HEADER in each
140e751525SEric Saxe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150e751525SEric Saxe  * If applicable, add the following below this CDDL HEADER, with the
160e751525SEric Saxe  * fields enclosed by brackets "[]" replaced with your own identifying
170e751525SEric Saxe  * information: Portions Copyright [yyyy] [name of copyright owner]
180e751525SEric Saxe  *
190e751525SEric Saxe  * CDDL HEADER END
200e751525SEric Saxe  */
210e751525SEric Saxe /*
220e751525SEric Saxe  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230e751525SEric Saxe  * Use is subject to license terms.
240e751525SEric Saxe  */
250e751525SEric Saxe 
260e751525SEric Saxe /*
27f21ed392Saubrey.li@intel.com  * Copyright (c) 2009, Intel Corporation.
28f21ed392Saubrey.li@intel.com  * All rights reserved.
29f21ed392Saubrey.li@intel.com  */
30f21ed392Saubrey.li@intel.com 
31f21ed392Saubrey.li@intel.com /*
320e751525SEric Saxe  * Intel specific CPU power management support.
330e751525SEric Saxe  */
340e751525SEric Saxe 
350e751525SEric Saxe #include <sys/x86_archext.h>
360e751525SEric Saxe #include <sys/cpu_acpi.h>
370e751525SEric Saxe #include <sys/speedstep.h>
380e751525SEric Saxe #include <sys/cpupm_throttle.h>
390e751525SEric Saxe #include <sys/cpu_idle.h>
40f21ed392Saubrey.li@intel.com #include <sys/archsystm.h>
410e751525SEric Saxe 
420e751525SEric Saxe /*
430e751525SEric Saxe  * The Intel Processor Driver Capabilities (_PDC).
440e751525SEric Saxe  * See Intel Processor Vendor-Specific ACPI Interface Specification
450e751525SEric Saxe  * for details.
460e751525SEric Saxe  */
470e751525SEric Saxe #define	CPUPM_INTEL_PDC_REVISION	0x1
480e751525SEric Saxe #define	CPUPM_INTEL_PDC_PS_MSR		0x0001
490e751525SEric Saxe #define	CPUPM_INTEL_PDC_C1_HALT		0x0002
500e751525SEric Saxe #define	CPUPM_INTEL_PDC_TS_MSR		0x0004
510e751525SEric Saxe #define	CPUPM_INTEL_PDC_MP		0x0008
520e751525SEric Saxe #define	CPUPM_INTEL_PDC_C2C3_MP		0x0010
530e751525SEric Saxe #define	CPUPM_INTEL_PDC_SW_PSD		0x0020
540e751525SEric Saxe #define	CPUPM_INTEL_PDC_TSD		0x0080
550e751525SEric Saxe #define	CPUPM_INTEL_PDC_C1_FFH		0x0100
560e751525SEric Saxe #define	CPUPM_INTEL_PDC_HW_PSD		0x0800
570e751525SEric Saxe 
580e751525SEric Saxe static uint32_t cpupm_intel_pdccap = 0;
590e751525SEric Saxe 
60f21ed392Saubrey.li@intel.com /*
61f21ed392Saubrey.li@intel.com  * MSR for Intel ENERGY_PERF_BIAS feature.
62f21ed392Saubrey.li@intel.com  * The default processor power operation policy is max performance.
63f21ed392Saubrey.li@intel.com  * Power control unit drives to max performance at any energy cost.
64f21ed392Saubrey.li@intel.com  * This MSR is designed to be a power master control knob,
65f21ed392Saubrey.li@intel.com  * it provides 4-bit OS input to the HW for the logical CPU, based on
66f21ed392Saubrey.li@intel.com  * user power-policy preference(scale of 0 to 15). 0 is highest
67f21ed392Saubrey.li@intel.com  * performance, 15 is minimal energy consumption.
68f21ed392Saubrey.li@intel.com  * 7 is a good balance between performance and energy consumption.
69f21ed392Saubrey.li@intel.com  */
70f21ed392Saubrey.li@intel.com #define	IA32_ENERGY_PERF_BIAS_MSR	0x1B0
71f21ed392Saubrey.li@intel.com #define	EPB_MSR_MASK			0xF
72f21ed392Saubrey.li@intel.com #define	EPB_MAX_PERF			0
73f21ed392Saubrey.li@intel.com #define	EPB_BALANCE			7
74f21ed392Saubrey.li@intel.com #define	EPB_MAX_POWER_SAVE		15
75f21ed392Saubrey.li@intel.com 
76f21ed392Saubrey.li@intel.com /*
77f21ed392Saubrey.li@intel.com  * The value is used to initialize the user power policy preference
78f21ed392Saubrey.li@intel.com  * in IA32_ENERGY_PERF_BIAS_MSR. Variable is used here to allow tuning
79f21ed392Saubrey.li@intel.com  * from the /etc/system file.
80f21ed392Saubrey.li@intel.com  */
81f21ed392Saubrey.li@intel.com uint64_t cpupm_iepb_policy = EPB_MAX_PERF;
82f21ed392Saubrey.li@intel.com 
83f21ed392Saubrey.li@intel.com static void cpupm_iepb_set_policy(uint64_t power_policy);
84f21ed392Saubrey.li@intel.com 
850e751525SEric Saxe boolean_t
cpupm_intel_init(cpu_t * cp)860e751525SEric Saxe cpupm_intel_init(cpu_t *cp)
870e751525SEric Saxe {
880e751525SEric Saxe 	cpupm_mach_state_t *mach_state =
890e751525SEric Saxe 	    (cpupm_mach_state_t *)(cp->cpu_m.mcpu_pm_mach_state);
900e751525SEric Saxe 	uint_t family;
910e751525SEric Saxe 	uint_t model;
920e751525SEric Saxe 
930e751525SEric Saxe 	if (x86_vendor != X86_VENDOR_Intel)
940e751525SEric Saxe 		return (B_FALSE);
950e751525SEric Saxe 
96*a3114836SGerry Liu 	family = cpuid_getfamily(cp);
97*a3114836SGerry Liu 	model = cpuid_getmodel(cp);
980e751525SEric Saxe 
990e751525SEric Saxe 	cpupm_intel_pdccap = CPUPM_INTEL_PDC_MP;
1000e751525SEric Saxe 
1010e751525SEric Saxe 	/*
1020e751525SEric Saxe 	 * If we support SpeedStep on this processor, then set the
1030e751525SEric Saxe 	 * correct cma_ops for the processor and enable appropriate
1040e751525SEric Saxe 	 * _PDC bits.
1050e751525SEric Saxe 	 */
1060e751525SEric Saxe 	if (speedstep_supported(family, model)) {
1070e751525SEric Saxe 		mach_state->ms_pstate.cma_ops = &speedstep_ops;
1080e751525SEric Saxe 		cpupm_intel_pdccap |= CPUPM_INTEL_PDC_PS_MSR |
1090e751525SEric Saxe 		    CPUPM_INTEL_PDC_C1_HALT | CPUPM_INTEL_PDC_SW_PSD |
1100e751525SEric Saxe 		    CPUPM_INTEL_PDC_HW_PSD;
1110e751525SEric Saxe 	} else {
1120e751525SEric Saxe 		mach_state->ms_pstate.cma_ops = NULL;
1130e751525SEric Saxe 	}
1140e751525SEric Saxe 
1150e751525SEric Saxe 	/*
1160e751525SEric Saxe 	 * Set the correct tstate_ops for the processor and
1170e751525SEric Saxe 	 * enable appropriate _PDC bits.
1180e751525SEric Saxe 	 */
1190e751525SEric Saxe 	mach_state->ms_tstate.cma_ops = &cpupm_throttle_ops;
1200e751525SEric Saxe 	cpupm_intel_pdccap |= CPUPM_INTEL_PDC_TS_MSR |
1210e751525SEric Saxe 	    CPUPM_INTEL_PDC_TSD;
1220e751525SEric Saxe 
1230e751525SEric Saxe 	/*
1240e751525SEric Saxe 	 * If we support deep cstates on this processor, then set the
1250e751525SEric Saxe 	 * correct cstate_ops for the processor and enable appropriate
1260e751525SEric Saxe 	 * _PDC bits.
1270e751525SEric Saxe 	 */
1280e751525SEric Saxe 	mach_state->ms_cstate.cma_ops = &cpu_idle_ops;
1290e751525SEric Saxe 	cpupm_intel_pdccap |= CPUPM_INTEL_PDC_C1_HALT |
1300e751525SEric Saxe 	    CPUPM_INTEL_PDC_C2C3_MP | CPUPM_INTEL_PDC_C1_FFH;
1310e751525SEric Saxe 
1320e751525SEric Saxe 	/*
1330e751525SEric Saxe 	 * _PDC support is optional and the driver should
1340e751525SEric Saxe 	 * function even if the _PDC write fails.
1350e751525SEric Saxe 	 */
1360e751525SEric Saxe 	(void) cpu_acpi_write_pdc(mach_state->ms_acpi_handle,
1370e751525SEric Saxe 	    CPUPM_INTEL_PDC_REVISION, 1, &cpupm_intel_pdccap);
1380e751525SEric Saxe 
139f21ed392Saubrey.li@intel.com 	/*
140f21ed392Saubrey.li@intel.com 	 * If Intel ENERGY PERFORMANCE BIAS feature is supported,
141f21ed392Saubrey.li@intel.com 	 * provides input to the HW, based on user power-policy.
142f21ed392Saubrey.li@intel.com 	 */
143f21ed392Saubrey.li@intel.com 	if (cpuid_iepb_supported(cp)) {
144f21ed392Saubrey.li@intel.com 		cpupm_iepb_set_policy(cpupm_iepb_policy);
145f21ed392Saubrey.li@intel.com 	}
146f21ed392Saubrey.li@intel.com 
1470e751525SEric Saxe 	return (B_TRUE);
1480e751525SEric Saxe }
149f21ed392Saubrey.li@intel.com 
150f21ed392Saubrey.li@intel.com /*
151f21ed392Saubrey.li@intel.com  * ENERGY_PERF_BIAS setting,
152f21ed392Saubrey.li@intel.com  * A hint to HW, based on user power-policy
153f21ed392Saubrey.li@intel.com  */
154f21ed392Saubrey.li@intel.com static void
cpupm_iepb_set_policy(uint64_t iepb_policy)155f21ed392Saubrey.li@intel.com cpupm_iepb_set_policy(uint64_t iepb_policy)
156f21ed392Saubrey.li@intel.com {
157f21ed392Saubrey.li@intel.com 	ulong_t		iflag;
158f21ed392Saubrey.li@intel.com 	uint64_t	epb_value;
159f21ed392Saubrey.li@intel.com 
160f21ed392Saubrey.li@intel.com 	epb_value = iepb_policy & EPB_MSR_MASK;
161f21ed392Saubrey.li@intel.com 
162f21ed392Saubrey.li@intel.com 	iflag = intr_clear();
163f21ed392Saubrey.li@intel.com 	wrmsr(IA32_ENERGY_PERF_BIAS_MSR, epb_value);
164f21ed392Saubrey.li@intel.com 	intr_restore(iflag);
165f21ed392Saubrey.li@intel.com }
166