cpupm_mach.h revision 8935:5bd81ee07936
1214152Sed/* 2214152Sed * CDDL HEADER START 3214152Sed * 4214152Sed * The contents of this file are subject to the terms of the 5222656Sed * Common Development and Distribution License (the "License"). 6222656Sed * You may not use this file except in compliance with the License. 7214152Sed * 8214152Sed * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9214152Sed * or http://www.opensolaris.org/os/licensing. 10214152Sed * See the License for the specific language governing permissions 11214152Sed * and limitations under the License. 12214152Sed * 13214152Sed * When distributing Covered Code, include this CDDL HEADER in each 14214152Sed * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15214152Sed * If applicable, add the following below this CDDL HEADER, with the 16229135Sed * fields enclosed by brackets "[]" replaced with your own identifying 17214152Sed * information: Portions Copyright [yyyy] [name of copyright owner] 18214152Sed * 19214152Sed * CDDL HEADER END 20214152Sed */ 21214152Sed/* 22214152Sed * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23214152Sed * Use is subject to license terms. 24214152Sed */ 25214152Sed 26214152Sed#ifndef _CPUPM_MACH_H 27214152Sed#define _CPUPM_MACH_H 28214152Sed 29214152Sed#ifdef __cplusplus 30229135Sedextern "C" { 31214152Sed#endif 32214152Sed 33229135Sed#include <sys/ddi.h> 34214152Sed#include <sys/sunddi.h> 35229135Sed#include <sys/cpuvar.h> 36229135Sed#include <sys/ksynch.h> 37229135Sed#include <sys/cpu_pm.h> 38229135Sed 39229135Sed/* 40229135Sed * CPU power domains 41214152Sed */ 42214152Sedtypedef struct cpupm_state_domains { 43229135Sed struct cpupm_state_domains *pm_next; 44214152Sed uint32_t pm_domain; 45229135Sed uint32_t pm_type; 46229135Sed cpuset_t pm_cpus; 47229135Sed kmutex_t pm_lock; 48229135Sed} cpupm_state_domains_t; 49229135Sed 50229135Sedextern cpupm_state_domains_t *cpupm_pstate_domains; 51214152Sedextern cpupm_state_domains_t *cpupm_tstate_domains; 52214152Sedextern cpupm_state_domains_t *cpupm_cstate_domains; 53229135Sed 54229135Sed/* 55214152Sed * Different processor families have their own technologies for supporting 56229135Sed * CPU power management (i.e., Intel has Enhanced SpeedStep for some of its 57229135Sed * processors and AMD has PowerNow! for some of its processors). We support 58229135Sed * these different technologies via modules that export the interfaces 59229135Sed * described below. 60229135Sed * 61229135Sed * If a module implements the technology that should be used to manage 62229135Sed * the current CPU device, then the cpus_init() module should return 63229135Sed * succesfully (i.e., return code of 0) and perform any initialization 64214152Sed * such that future power transistions can be performed by calling 65214152Sed * the cpus_change() interface. And the cpups_fini() interface can be 66214152Sed * used to free any resources allocated by cpus_init(). 67214152Sed */ 68229135Sedtypedef struct cpupm_state_ops { 69229135Sed char *cpups_label; 70214152Sed int (*cpus_init)(cpu_t *); 71214152Sed void (*cpus_fini)(cpu_t *); 72214152Sed void (*cpus_change)(cpuset_t, uint32_t); 73214152Sed} cpupm_state_ops_t; 74 75/* 76 * Data kept for each C-state power-domain. 77 */ 78typedef struct cma_c_state { 79 uint32_t cs_next_cstate; /* computed best C-state */ 80 81 uint32_t cs_cnt; /* times accessed */ 82 uint32_t cs_type; /* current ACPI idle type */ 83 84 hrtime_t cs_idle_enter; /* entered idle */ 85 hrtime_t cs_idle_exit; /* left idle */ 86 87 hrtime_t cs_smpl_start; /* accounting sample began */ 88 hrtime_t cs_idle; /* time idle */ 89 hrtime_t cs_smpl_len; /* sample duration */ 90 hrtime_t cs_smpl_idle; /* idle time in last sample */ 91 uint64_t cs_smpl_idle_pct; /* % idle time in last smpl */ 92 93 hrtime_t cs_C2_latency; /* C2 round trip latency */ 94 hrtime_t cs_C3_latency; /* C3 round trip latency */ 95} cma_c_state_t; 96 97typedef union cma_state { 98 cma_c_state_t *cstate; 99 uint32_t pstate; 100} cma_state_t; 101 102typedef struct cpupm_mach_acpi_state { 103 cpupm_state_ops_t *cma_ops; 104 cpupm_state_domains_t *cma_domain; 105 cma_state_t cma_state; 106} cpupm_mach_acpi_state_t; 107 108typedef struct cpupm_mach_state { 109 void *ms_acpi_handle; 110 cpupm_mach_acpi_state_t ms_pstate; 111 cpupm_mach_acpi_state_t ms_cstate; 112 cpupm_mach_acpi_state_t ms_tstate; 113 uint32_t ms_caps; 114 dev_info_t *ms_dip; 115 kmutex_t ms_lock; 116 void *ms_vendor; 117 struct cpupm_notification *ms_handlers; 118} cpupm_mach_state_t; 119 120/* 121 * Constants used by the Processor Device Notification handler 122 * that identify what kind of change has occurred. 123 */ 124#define CPUPM_PPC_CHANGE_NOTIFICATION 0x80 125#define CPUPM_CST_CHANGE_NOTIFICATION 0x81 126#define CPUPM_TPC_CHANGE_NOTIFICATION 0x82 127 128typedef void (*CPUPM_NOTIFY_HANDLER)(void *handle, uint32_t val, 129 void *ctx); 130 131typedef struct cpupm_notification { 132 struct cpupm_notification *nq_next; 133 CPUPM_NOTIFY_HANDLER nq_handler; 134 void *nq_ctx; 135} cpupm_notification_t; 136 137/* 138 * If any states are added, then make sure to add them to 139 * CPUPM_ALL_STATES. 140 */ 141#define CPUPM_NO_STATES 0x00 142#define CPUPM_P_STATES 0x01 143#define CPUPM_T_STATES 0x02 144#define CPUPM_C_STATES 0x04 145#define CPUPM_ALL_STATES (CPUPM_P_STATES \ 146 | CPUPM_T_STATES \ 147 | CPUPM_C_STATES) 148 149#define CPUPM_XCALL_IS_READY(cpuid) CPU_IN_SET(cpu_ready_set, (cpuid)) 150 151/* 152 * An error in initializing any of the CPU PM results in disabling 153 * CPU power management. 154 */ 155#define CPUPM_DISABLE() cpupm_disable(CPUPM_ALL_STATES) 156 157#define CPUPM_SPEED_HZ(unused, mhz) ((uint64_t)mhz * 1000000) 158 159/* 160 * Callbacks used for CPU power management. 161 */ 162extern void (*cpupm_rebuild_cpu_domains)(void); 163extern void (*cpupm_init_topspeed)(void); 164extern void (*cpupm_redefine_topspeed)(void *); 165extern int (*cpupm_get_topspeed_callb)(void *); 166extern void (*cpupm_set_topspeed_callb)(void *, int); 167 168extern void cpupm_init(cpu_t *); 169extern void cpupm_free(cpu_t *); 170extern boolean_t cpupm_is_ready(); 171extern boolean_t cpupm_is_enabled(uint32_t); 172extern void cpupm_disable(uint32_t); 173extern void cpupm_post_startup(); 174extern void cpupm_alloc_domains(cpu_t *, int); 175extern void cpupm_free_domains(cpupm_state_domains_t **); 176extern void cpupm_alloc_ms_cstate(cpu_t *cp); 177extern void cpupm_free_ms_cstate(cpu_t *cp); 178extern void cpupm_state_change(cpu_t *, int, int); 179extern id_t cpupm_plat_domain_id(cpu_t *cp, cpupm_dtype_t type); 180extern uint_t cpupm_plat_state_enumerate(cpu_t *, cpupm_dtype_t, 181 cpupm_state_t *); 182extern int cpupm_plat_change_state(cpu_t *, cpupm_state_t *); 183extern uint_t cpupm_get_speeds(cpu_t *, int **); 184extern void cpupm_free_speeds(int *, uint_t); 185extern boolean_t cpupm_power_ready(void); 186extern boolean_t cpupm_throttle_ready(void); 187extern boolean_t cpupm_cstate_ready(void); 188extern void cpupm_add_notify_handler(cpu_t *, CPUPM_NOTIFY_HANDLER, void *); 189extern int cpupm_get_top_speed(cpu_t *); 190extern uint32_t cpupm_next_cstate(cma_c_state_t *, hrtime_t); 191extern void cpupm_idle_cstate_data(cma_c_state_t *, int); 192extern void cpupm_wakeup_cstate_data(cma_c_state_t *, hrtime_t); 193 194#ifdef __cplusplus 195} 196#endif 197 198#endif /* _CPUPM_MACH_H */ 199