Home | History | Annotate | Download | only in sys
      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  * Copyright (c) 2009,  Intel Corporation.
     27  * All Rights Reserved.
     28  */
     29 
     30 #ifndef	_CPUPM_MACH_H
     31 #define	_CPUPM_MACH_H
     32 
     33 #ifdef __cplusplus
     34 extern "C" {
     35 #endif
     36 
     37 #include <sys/ddi.h>
     38 #include <sys/sunddi.h>
     39 #include <sys/cpuvar.h>
     40 #include <sys/ksynch.h>
     41 #include <sys/cpu_pm.h>
     42 
     43 /*
     44  * CPU power domains
     45  */
     46 typedef struct cpupm_state_domains {
     47 	struct cpupm_state_domains	*pm_next;
     48 	uint32_t			pm_domain;
     49 	uint32_t			pm_type;
     50 	cpuset_t			pm_cpus;
     51 	kmutex_t			pm_lock;
     52 } cpupm_state_domains_t;
     53 
     54 extern cpupm_state_domains_t *cpupm_pstate_domains;
     55 extern cpupm_state_domains_t *cpupm_tstate_domains;
     56 extern cpupm_state_domains_t *cpupm_cstate_domains;
     57 
     58 /*
     59  * Different processor families have their own technologies for supporting
     60  * CPU power management (i.e., Intel has Enhanced SpeedStep for some of its
     61  * processors and AMD has PowerNow! for some of its processors). We support
     62  * these different technologies via modules that export the interfaces
     63  * described below.
     64  *
     65  * If a module implements the technology that should be used to manage
     66  * the current CPU device, then the cpus_init() module should return
     67  * succesfully (i.e., return code of 0) and perform any initialization
     68  * such that future power transistions can be performed by calling
     69  * the cpus_change() interface. And the cpups_fini() interface can be
     70  * used to free any resources allocated by cpus_init().
     71  */
     72 typedef struct cpupm_state_ops {
     73 	char	*cpups_label;
     74 	int	(*cpus_init)(cpu_t *);
     75 	void	(*cpus_fini)(cpu_t *);
     76 	void	(*cpus_change)(cpuset_t, uint32_t);
     77 	void	(*cpus_stop)(cpu_t *);
     78 } cpupm_state_ops_t;
     79 
     80 /*
     81  * Data kept for each C-state power-domain.
     82  */
     83 typedef struct cma_c_state {
     84 	uint32_t	cs_next_cstate;	/* computed best C-state */
     85 
     86 	uint32_t	cs_cnt;		/* times accessed */
     87 	uint32_t	cs_type;	/* current ACPI idle type */
     88 
     89 	hrtime_t	cs_idle_enter;	/* entered idle */
     90 	hrtime_t	cs_idle_exit;	/* left idle */
     91 
     92 	hrtime_t	cs_smpl_start;	/* accounting sample began */
     93 	hrtime_t	cs_idle;	/* time idle */
     94 	hrtime_t	cs_smpl_len;	/* sample duration */
     95 	hrtime_t	cs_smpl_idle;	/* idle time in last sample */
     96 	uint64_t	cs_smpl_idle_pct;	/* % idle time in last smpl */
     97 } cma_c_state_t;
     98 
     99 typedef union cma_state {
    100 	cma_c_state_t	*cstate;
    101 	uint32_t	pstate;
    102 } cma_state_t;
    103 
    104 typedef struct cpupm_mach_acpi_state {
    105 	cpupm_state_ops_t	*cma_ops;
    106 	cpupm_state_domains_t   *cma_domain;
    107 	cma_state_t		cma_state;
    108 } cpupm_mach_acpi_state_t;
    109 
    110 typedef struct cpupm_mach_state {
    111 	void			*ms_acpi_handle;
    112 	cpupm_mach_acpi_state_t	ms_pstate;
    113 	cpupm_mach_acpi_state_t	ms_cstate;
    114 	cpupm_mach_acpi_state_t	ms_tstate;
    115 	uint32_t		ms_caps;
    116 	dev_info_t		*ms_dip;
    117 	kmutex_t		ms_lock;
    118 	void			*ms_vendor;
    119 	struct cpupm_notification *ms_handlers;
    120 } cpupm_mach_state_t;
    121 
    122 /*
    123  * Constants used by the Processor Device Notification handler
    124  * that identify what kind of change has occurred.
    125  */
    126 #define	CPUPM_PPC_CHANGE_NOTIFICATION 0x80
    127 #define	CPUPM_CST_CHANGE_NOTIFICATION 0x81
    128 #define	CPUPM_TPC_CHANGE_NOTIFICATION 0x82
    129 
    130 typedef void (*CPUPM_NOTIFY_HANDLER)(void *handle, uint32_t val,
    131     void *ctx);
    132 
    133 typedef struct cpupm_notification {
    134 	struct cpupm_notification	*nq_next;
    135 	CPUPM_NOTIFY_HANDLER		nq_handler;
    136 	void				*nq_ctx;
    137 } cpupm_notification_t;
    138 
    139 /*
    140  * If any states are added, then make sure to add them to
    141  * CPUPM_ALL_STATES.
    142  */
    143 #define	CPUPM_NO_STATES		0x00
    144 #define	CPUPM_P_STATES		0x01
    145 #define	CPUPM_T_STATES		0x02
    146 #define	CPUPM_C_STATES		0x04
    147 #define	CPUPM_ALL_STATES	(CPUPM_P_STATES \
    148 				| CPUPM_T_STATES \
    149 				| CPUPM_C_STATES)
    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  */
    162 extern void (*cpupm_ppm_alloc_pstate_domains)(cpu_t *);
    163 extern void (*cpupm_ppm_free_pstate_domains)(cpu_t *);
    164 extern void (*cpupm_redefine_topspeed)(void *);
    165 extern int (*cpupm_get_topspeed_callb)(void *);
    166 extern void (*cpupm_set_topspeed_callb)(void *, int);
    167 
    168 extern void cpupm_init(cpu_t *);
    169 extern void cpupm_fini(cpu_t *);
    170 extern void cpupm_start(cpu_t *);
    171 extern void cpupm_stop(cpu_t *);
    172 extern boolean_t cpupm_is_ready(cpu_t *);
    173 extern boolean_t cpupm_is_enabled(uint32_t);
    174 extern void cpupm_disable(uint32_t);
    175 extern void cpupm_alloc_domains(cpu_t *, int);
    176 extern void cpupm_free_domains(cpupm_state_domains_t **);
    177 extern void cpupm_remove_domains(cpu_t *, int, cpupm_state_domains_t **);
    178 extern void cpupm_alloc_ms_cstate(cpu_t *cp);
    179 extern void cpupm_free_ms_cstate(cpu_t *cp);
    180 extern void cpupm_state_change(cpu_t *, int, int);
    181 extern id_t cpupm_plat_domain_id(cpu_t *cp, cpupm_dtype_t type);
    182 extern uint_t cpupm_plat_state_enumerate(cpu_t *, cpupm_dtype_t,
    183     cpupm_state_t *);
    184 extern int cpupm_plat_change_state(cpu_t *, cpupm_state_t *);
    185 extern uint_t cpupm_get_speeds(cpu_t *, int **);
    186 extern void cpupm_free_speeds(int *, uint_t);
    187 extern boolean_t cpupm_power_ready(cpu_t *);
    188 extern boolean_t cpupm_throttle_ready(cpu_t *);
    189 extern boolean_t cpupm_cstate_ready(cpu_t *);
    190 extern void cpupm_add_notify_handler(cpu_t *, CPUPM_NOTIFY_HANDLER, void *);
    191 extern int cpupm_get_top_speed(cpu_t *);
    192 extern void cpupm_idle_cstate_data(cma_c_state_t *, int);
    193 extern void cpupm_wakeup_cstate_data(cma_c_state_t *, hrtime_t);
    194 
    195 #ifdef __cplusplus
    196 }
    197 #endif
    198 
    199 #endif	/* _CPUPM_MACH_H */
    200