17f606aceSMark Haywood /*
27f606aceSMark Haywood * CDDL HEADER START
37f606aceSMark Haywood *
47f606aceSMark Haywood * The contents of this file are subject to the terms of the
57f606aceSMark Haywood * Common Development and Distribution License (the "License").
67f606aceSMark Haywood * You may not use this file except in compliance with the License.
77f606aceSMark Haywood *
87f606aceSMark Haywood * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97f606aceSMark Haywood * or http://www.opensolaris.org/os/licensing.
107f606aceSMark Haywood * See the License for the specific language governing permissions
117f606aceSMark Haywood * and limitations under the License.
127f606aceSMark Haywood *
137f606aceSMark Haywood * When distributing Covered Code, include this CDDL HEADER in each
147f606aceSMark Haywood * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157f606aceSMark Haywood * If applicable, add the following below this CDDL HEADER, with the
167f606aceSMark Haywood * fields enclosed by brackets "[]" replaced with your own identifying
177f606aceSMark Haywood * information: Portions Copyright [yyyy] [name of copyright owner]
187f606aceSMark Haywood *
197f606aceSMark Haywood * CDDL HEADER END
207f606aceSMark Haywood */
217f606aceSMark Haywood /*
2284e1ed42SMark Haywood * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237f606aceSMark Haywood * Use is subject to license terms.
247f606aceSMark Haywood */
257f606aceSMark Haywood
26f21ed392Saubrey.li@intel.com /*
27f21ed392Saubrey.li@intel.com * Copyright (c) 2009, Intel Corporation.
28f21ed392Saubrey.li@intel.com * All rights reserved.
29f21ed392Saubrey.li@intel.com */
30f21ed392Saubrey.li@intel.com
317f606aceSMark Haywood /*
327f606aceSMark Haywood * Intel specific CPU power management support.
337f606aceSMark Haywood */
347f606aceSMark Haywood
357f606aceSMark Haywood #include <sys/x86_archext.h>
367f606aceSMark Haywood #include <sys/cpu_acpi.h>
377f606aceSMark Haywood #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>
417f606aceSMark Haywood
427f606aceSMark Haywood /*
437f606aceSMark Haywood * The Intel Processor Driver Capabilities (_PDC).
447f606aceSMark Haywood * See Intel Processor Vendor-Specific ACPI Interface Specification
457f606aceSMark Haywood * for details.
467f606aceSMark Haywood */
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
577f606aceSMark Haywood
580e751525SEric Saxe static uint32_t cpupm_intel_pdccap = 0;
597f606aceSMark Haywood
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
857f606aceSMark Haywood boolean_t
cpupm_intel_init(cpu_t * cp)860e751525SEric Saxe cpupm_intel_init(cpu_t *cp)
877f606aceSMark Haywood {
880e751525SEric Saxe cpupm_mach_state_t *mach_state =
890e751525SEric Saxe (cpupm_mach_state_t *)(cp->cpu_m.mcpu_pm_mach_state);
907f606aceSMark Haywood uint_t family;
917f606aceSMark Haywood uint_t model;
927f606aceSMark Haywood
937f606aceSMark Haywood if (x86_vendor != X86_VENDOR_Intel)
947f606aceSMark Haywood return (B_FALSE);
957f606aceSMark Haywood
96*a3114836SGerry Liu family = cpuid_getfamily(cp);
97*a3114836SGerry Liu model = cpuid_getmodel(cp);
987f606aceSMark Haywood
990e751525SEric Saxe cpupm_intel_pdccap = CPUPM_INTEL_PDC_MP;
1000e751525SEric Saxe
1017f606aceSMark Haywood /*
1027f606aceSMark Haywood * If we support SpeedStep on this processor, then set the
1030e751525SEric Saxe * correct cma_ops for the processor and enable appropriate
1047f606aceSMark Haywood * _PDC bits.
1057f606aceSMark Haywood */
1067f606aceSMark Haywood 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;
1117f606aceSMark Haywood } else {
1120e751525SEric Saxe mach_state->ms_pstate.cma_ops = NULL;
1137f606aceSMark Haywood }
1147f606aceSMark Haywood
1157f606aceSMark Haywood /*
1167f606aceSMark Haywood * Set the correct tstate_ops for the processor and
1177f606aceSMark Haywood * enable appropriate _PDC bits.
1187f606aceSMark Haywood */
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;
1317f606aceSMark Haywood
1327f606aceSMark Haywood /*
1337f606aceSMark Haywood * _PDC support is optional and the driver should
1347f606aceSMark Haywood * function even if the _PDC write fails.
1357f606aceSMark Haywood */
1360e751525SEric Saxe (void) cpu_acpi_write_pdc(mach_state->ms_acpi_handle,
1370e751525SEric Saxe CPUPM_INTEL_PDC_REVISION, 1, &cpupm_intel_pdccap);
1387f606aceSMark Haywood
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
1477f606aceSMark Haywood return (B_TRUE);
1487f606aceSMark Haywood }
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