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