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 * Copyright (c) 2009, Intel Corporation. 28 * All rights reserved. 29 */ 30 31 /* 32 * Intel specific CPU power management support. 33 */ 34 35 #include <sys/x86_archext.h> 36 #include <sys/cpu_acpi.h> 37 #include <sys/speedstep.h> 38 #include <sys/cpupm_throttle.h> 39 #include <sys/cpu_idle.h> 40 #include <sys/archsystm.h> 41 42 /* 43 * The Intel Processor Driver Capabilities (_PDC). 44 * See Intel Processor Vendor-Specific ACPI Interface Specification 45 * for details. 46 */ 47 #define CPUPM_INTEL_PDC_REVISION 0x1 48 #define CPUPM_INTEL_PDC_PS_MSR 0x0001 49 #define CPUPM_INTEL_PDC_C1_HALT 0x0002 50 #define CPUPM_INTEL_PDC_TS_MSR 0x0004 51 #define CPUPM_INTEL_PDC_MP 0x0008 52 #define CPUPM_INTEL_PDC_C2C3_MP 0x0010 53 #define CPUPM_INTEL_PDC_SW_PSD 0x0020 54 #define CPUPM_INTEL_PDC_TSD 0x0080 55 #define CPUPM_INTEL_PDC_C1_FFH 0x0100 56 #define CPUPM_INTEL_PDC_HW_PSD 0x0800 57 58 static uint32_t cpupm_intel_pdccap = 0; 59 60 /* 61 * MSR for Intel ENERGY_PERF_BIAS feature. 62 * The default processor power operation policy is max performance. 63 * Power control unit drives to max performance at any energy cost. 64 * This MSR is designed to be a power master control knob, 65 * it provides 4-bit OS input to the HW for the logical CPU, based on 66 * user power-policy preference(scale of 0 to 15). 0 is highest 67 * performance, 15 is minimal energy consumption. 68 * 7 is a good balance between performance and energy consumption. 69 */ 70 #define IA32_ENERGY_PERF_BIAS_MSR 0x1B0 71 #define EPB_MSR_MASK 0xF 72 #define EPB_MAX_PERF 0 73 #define EPB_BALANCE 7 74 #define EPB_MAX_POWER_SAVE 15 75 76 /* 77 * The value is used to initialize the user power policy preference 78 * in IA32_ENERGY_PERF_BIAS_MSR. Variable is used here to allow tuning 79 * from the /etc/system file. 80 */ 81 uint64_t cpupm_iepb_policy = EPB_MAX_PERF; 82 83 static void cpupm_iepb_set_policy(uint64_t power_policy); 84 85 boolean_t 86 cpupm_intel_init(cpu_t *cp) 87 { 88 cpupm_mach_state_t *mach_state = 89 (cpupm_mach_state_t *)(cp->cpu_m.mcpu_pm_mach_state); 90 uint_t family; 91 uint_t model; 92 93 if (x86_vendor != X86_VENDOR_Intel) 94 return (B_FALSE); 95 96 family = cpuid_getfamily(CPU); 97 model = cpuid_getmodel(CPU); 98 99 cpupm_intel_pdccap = CPUPM_INTEL_PDC_MP; 100 101 /* 102 * If we support SpeedStep on this processor, then set the 103 * correct cma_ops for the processor and enable appropriate 104 * _PDC bits. 105 */ 106 if (speedstep_supported(family, model)) { 107 mach_state->ms_pstate.cma_ops = &speedstep_ops; 108 cpupm_intel_pdccap |= CPUPM_INTEL_PDC_PS_MSR | 109 CPUPM_INTEL_PDC_C1_HALT | CPUPM_INTEL_PDC_SW_PSD | 110 CPUPM_INTEL_PDC_HW_PSD; 111 } else { 112 mach_state->ms_pstate.cma_ops = NULL; 113 } 114 115 /* 116 * Set the correct tstate_ops for the processor and 117 * enable appropriate _PDC bits. 118 */ 119 mach_state->ms_tstate.cma_ops = &cpupm_throttle_ops; 120 cpupm_intel_pdccap |= CPUPM_INTEL_PDC_TS_MSR | 121 CPUPM_INTEL_PDC_TSD; 122 123 /* 124 * If we support deep cstates on this processor, then set the 125 * correct cstate_ops for the processor and enable appropriate 126 * _PDC bits. 127 */ 128 mach_state->ms_cstate.cma_ops = &cpu_idle_ops; 129 cpupm_intel_pdccap |= CPUPM_INTEL_PDC_C1_HALT | 130 CPUPM_INTEL_PDC_C2C3_MP | CPUPM_INTEL_PDC_C1_FFH; 131 132 /* 133 * _PDC support is optional and the driver should 134 * function even if the _PDC write fails. 135 */ 136 (void) cpu_acpi_write_pdc(mach_state->ms_acpi_handle, 137 CPUPM_INTEL_PDC_REVISION, 1, &cpupm_intel_pdccap); 138 139 /* 140 * If Intel ENERGY PERFORMANCE BIAS feature is supported, 141 * provides input to the HW, based on user power-policy. 142 */ 143 if (cpuid_iepb_supported(cp)) { 144 cpupm_iepb_set_policy(cpupm_iepb_policy); 145 } 146 147 return (B_TRUE); 148 } 149 150 /* 151 * ENERGY_PERF_BIAS setting, 152 * A hint to HW, based on user power-policy 153 */ 154 static void 155 cpupm_iepb_set_policy(uint64_t iepb_policy) 156 { 157 ulong_t iflag; 158 uint64_t epb_value; 159 160 epb_value = iepb_policy & EPB_MSR_MASK; 161 162 iflag = intr_clear(); 163 wrmsr(IA32_ENERGY_PERF_BIAS_MSR, epb_value); 164 intr_restore(iflag); 165 } 166