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/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_SYSCTRL_H
28#define	_SYS_SYSCTRL_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36#ifndef	TRUE
37#define	TRUE (1)
38#endif
39#ifndef	FALSE
40#define	FALSE (0)
41#endif
42
43/*
44 * Debugging macros
45 *
46 * The DPRINTF macro can be used by setting the sysc_debug_print_level to the
47 * appropriate debugging level.  The debug levels are defined in each source
48 * file where this header file is included.  The scoping of sysc_debug_info,
49 * and sysc_debug_print_level is to the file which included the header file.
50 * If multiple levels need to be output, the values can be 'ored'
51 * together into sysc_debug_print_level.  If sysc_debug_print_line's bit 1 is
52 * set, the line number of the debugging statement is printed out. If it has
53 * bit 2 set, the macro will drop into either the debugger or the OBP PROM.
54 */
55
56#ifdef  DEBUG
57
58#define	SYSCTRL_ATTACH_DEBUG	0x1
59#define	SYSCTRL_INTERRUPT_DEBUG	0x2
60#define	SYSCTRL_REGISTERS_DEBUG	0x4
61#define	SYSC_DEBUG		SYSCTRL_ATTACH_DEBUG
62
63#include <sys/promif.h>
64extern void debug_enter(char *);
65
66extern int sysc_debug_info;
67extern int sysc_debug_print_level;
68
69#define	PRINT_LINE_NUMBER	0x1
70#define	ENTER_MON		0x2
71
72#define	_PRINTF prom_printf	/* For logging to the console */
73
74#define	DPRINTF(print_flag, args)			\
75	if (sysc_debug_print_level & (print_flag) && sysc_debug_info & \
76	    PRINT_LINE_NUMBER) \
77		_PRINTF("%s line %d:\n", __FILE__, __LINE__);	\
78	if (sysc_debug_print_level & (print_flag)) {	\
79		_PRINTF args;				\
80	if (sysc_debug_info & ENTER_MON)			\
81		debug_enter("");				\
82	}
83
84#else
85#define	DPRINTF(print_flag, args)
86#endif /* DEBUG */
87
88/*
89 * OBP supplies us with 3 register sets for the clock-board node. The code for
90 * the syctrl driver relies on these register sets being presented by the
91 * PROM in the order specified below. If this changes, the following comments
92 * must be revised and the code in sysctrl_attach() must be changed to reflect
93 * these revisions.
94 *
95 * They are:
96 * 	0	Clock frequency registers
97 *	1	Misc registers
98 *	2       Clock version register
99 */
100
101/*
102 * The offsets are defined as offsets in bytes from the base of the OBP
103 * register to which the register belongs to.
104 */
105
106/* Register set 0 */
107#define	SYS_OFF_CLK_FREQ2	0x2	/* offset of clock register 2 */
108
109/* Important bits for Clock Frequency register 2 */
110#define	RCONS_UART_EN	0x80	/* Remote console reset enabled */
111#define	GEN_RESET_EN	0x40	/* Enable reset on freq change */
112#define	TOD_RESET_EN	0x20	/* Enable reset from TOD watchdog */
113#define	CLOCK_FREQ_8	0x01	/* Frequency bit 8 */
114#define	CLOCK_DIV_0	0x02	/* Cpu module divisor bit 0 */
115#define	CLOCK_RANGE	0x0c	/* Bits 3:2 control the clock range */
116#define	CLOCK_DIV_1	0x10	/* Cpu module divisor bit 1 */
117
118/* Register set 1 */
119#define	SYS_OFF_CTRL	0x0	/* Offset of System Control register */
120#define	SYS_OFF_STAT1	0x10	/* Offset of System Status1 register */
121#define	SYS_OFF_STAT2	0x20	/* Offset of System Status2 register */
122#define	SYS_OFF_PSSTAT	0x30	/* Offset of Power Supply Status */
123#define	SYS_OFF_PSPRES	0x40	/* Offset of Power Supply Presence */
124#define	SYS_OFF_TEMP	0x50	/* Offset of temperature register */
125#define	SYS_OFF_DIAG	0x60	/* Offset of interrupt diag register */
126#define	SYS_OFF_PPPSR	0x70	/* Offset of second Power Supply Status */
127#define	SYS_STATUS1_PADDR	0x1fff8906010 /* physical address for physio */
128
129/* Register set 2 (not present on old vintage clock boards) */
130#define	CLK_VERSION_REG	0x0	/* Offset of clock version register */
131#define	CLK_VERSION_REG_PADDR 0x1fff890c000 /* physical address for physio */
132
133/* Important bits for the board version register */
134#define	OLD_CLK_GEN	0x1
135#define	OLD_CLK_DIV	0x2
136
137#define	RMT_CONS_OFFSET	0x4004	/* Offset of Remote Console UART */
138#define	RMT_CONS_LEN	0x8	/* Size of Remote Console UART */
139
140/* Bit field defines for System Control register */
141#define	SYS_PPS_FAN_FAIL_EN	0x80	/* PPS Fan Fail Interrupt Enable */
142#define	SYS_PS_FAIL_EN		0x40	/* PS DC Fail Interrupt Enable */
143#define	SYS_AC_PWR_FAIL_EN	0x20	/* AC Power Fail Interrupt Enable */
144#define	SYS_SBRD_PRES_EN	0x10	/* Board Insertion Interrupt En */
145#define	SYS_PWR_OFF		0x08	/* Bit to turn system power */
146#define	SYS_LED_LEFT		0x04	/* System Left LED. Reverse Logic */
147#define	SYS_LED_MID		0x02	/* System Middle LED */
148#define	SYS_LED_RIGHT		0x01	/* System Right LED */
149
150/* Bit field defines for System Status1 register */
151#define	SYS_SLOTS		0xC0	/* system type slot field */
152#define	SYS_NOT_SECURE		0x20	/* ==0 Keyswitch in secure pos. */
153#define	SYS_NOT_P_FAN_PRES	0x10	/* ==0 PPS cooling tray present */
154#define	SYS_NOT_BRD_PRES	0x08	/* ==0 When board inserted */
155#define	SYS_NOT_PPS0_PRES	0x04	/* ==0 If PPS0 present */
156#define	SYS_TOD_NOT_RST		0x02	/* ==0 if TOD reset occurred */
157#define	SYS_GEN_NOT_RST		0x01	/* ==0 if clock freq reset occured */
158
159/* Macros to determine system type from System Status1 register */
160#define	SYS_TYPE(x)		((x) & SYS_SLOTS)
161#define	SYS_16_SLOT		0x40
162#define	SYS_8_SLOT		0xC0
163#define	SYS_4_SLOT		0x80
164#define	SYS_TESTBED		0x00
165
166/* Bit field defines for Clock Version Register */
167#define	SYS_SLOTS2		0x80	/* system type slot2 mask */
168#define	SYS_PLUS_SYSTEM		0x00	/* bit 7 is low for plus system */
169
170/* Macros to determine frequency capability from clock version register */
171#define	SYS_TYPE2(x)		((x) & SYS_SLOTS2)
172#define	ISPLUSSYS(reg)		((reg != 0) && \
173					(SYS_TYPE2(*reg) == SYS_PLUS_SYSTEM))
174
175/* Macros to determine system type based on number of physical slots */
176#define	IS4SLOT(n)		((n) == 4)
177#define	IS5SLOT(n)		((n) == 5)
178#define	IS8SLOT(n)		((n) == 8)
179#define	IS16SLOT(n)		((n) == 16)
180#define	ISTESTBED(n)		((n) == 0)
181
182/* Bit field defines for System Status2 register */
183#define	SYS_RMTE_NOT_RST	0x80	/* Remote Console reset occurred */
184#define	SYS_PPS0_OK		0x40	/* ==1 PPS0 OK */
185#define	SYS_CLK_33_OK		0x20	/* 3.3V OK on clock board */
186#define	SYS_CLK_50_OK		0x10	/* 5.0V OK on clock board */
187#define	SYS_AC_FAIL		0x08	/* System lost AC Power source */
188#define	SYS_RACK_FANFAIL	0x04	/* Peripheral Rack fan status */
189#define	SYS_AC_FAN_OK		0x02	/* Status of 4 AC box fans */
190#define	SYS_KEYSW_FAN_OK	0x01	/* Status of keyswitch fan */
191
192/* Bit field defines for Power Supply Presence register */
193#define	SYS_NOT_PPS1_PRES	0x80	/* ==0 if PPS1 present in 4slot */
194
195/* Bit field defines for Precharge and Peripheral Power Status register */
196#define	SYS_NOT_CURRENT_S	0x80	/* Current share backplane */
197#define	SYS_PPPSR_BITS		0x7f	/* bulk test bit mask */
198#define	SYS_V5_P_OK		0x40	/* ==1 peripheral 5v ok */
199#define	SYS_V12_P_OK		0x20	/* ==1 peripheral 12v ok */
200#define	SYS_V5_AUX_OK		0x10	/* ==1 auxiliary 5v ok */
201#define	SYS_V5_P_PCH_OK		0x08	/* ==1 peripheral 5v precharge ok */
202#define	SYS_V12_P_PCH_OK	0x04	/* ==1 peripheral 12v precharge ok */
203#define	SYS_V3_PCH_OK		0x02	/* ==1 system 3.3v precharge ok */
204#define	SYS_V5_PCH_OK		0x01	/* ==1 system 5.0v precharge ok */
205
206#ifndef _ASM
207
208#define	SYSCTRL_KSTAT_NAME	"sysctrl"
209#define	CSR_KSTAT_NAMED		"csr"
210#define	STAT1_KSTAT_NAMED	"status1"
211#define	STAT2_KSTAT_NAMED	"status2"
212#define	CLK_FREQ2_KSTAT_NAMED	"clk_freq2"
213#define	FAN_KSTAT_NAMED		"fan_status"
214#define	KEY_KSTAT_NAMED		"key_status"
215#define	POWER_KSTAT_NAMED	"power_status"
216#define	BDLIST_KSTAT_NAME	"bd_list"
217#define	CLK_VER_KSTAT_NAME	"clk_ver"
218
219/*
220 * The Power Supply shadow kstat is too large to fit in a kstat_named
221 * struct, so it has been changed to be a raw kstat.
222 */
223#define	PSSHAD_KSTAT_NAME	"ps_shadow"
224
225/* States of a power supply DC voltage. */
226enum e_state { PS_BOOT = 0, PS_OUT, PS_UNKNOWN, PS_OK, PS_FAIL };
227enum e_pres_state { PRES_UNKNOWN = 0, PRES_IN, PRES_OUT };
228
229/*
230 * several power supplies are managed -- 8 core power supplies,
231 * up to two pps, a couple of clock board powers and a register worth
232 * of precharges.
233 */
234#define	SYS_PS_COUNT 19
235/* core PS 0 thru 7 are index 0 thru 7 */
236#define	SYS_PPS0_INDEX		8
237#define	SYS_CLK_33_INDEX	9
238#define	SYS_CLK_50_INDEX	10
239#define	SYS_V5_P_INDEX		11
240#define	SYS_V12_P_INDEX		12
241#define	SYS_V5_AUX_INDEX	13
242#define	SYS_V5_P_PCH_INDEX	14
243#define	SYS_V12_P_PCH_INDEX	15
244#define	SYS_V3_PCH_INDEX	16
245#define	SYS_V5_PCH_INDEX	17
246#define	SYS_P_FAN_INDEX		18	/* the peripheral fan assy */
247
248/* fan timeout structures */
249enum pps_fan_type { RACK = 0, AC = 1, KEYSW = 2 };
250#define	SYS_PPS_FAN_COUNT	3
251
252/*
253 * States of the secure key switch position.
254 */
255enum keyswitch_state { KEY_BOOT = 0, KEY_SECURE, KEY_NOT_SECURE };
256
257/* Redundant power states */
258enum power_state { BOOT = 0, BELOW_MINIMUM, MINIMUM, REDUNDANT };
259
260/*
261 * minor device mask
262 * B	- bottom 4 bits (16 slots) are for the slot/receptacle id
263 * I	- next 4 bits are for the instance number
264 * X	- rest are not used
265 *
266 * Upper                  Lower
267 * XXXXX...............IIIIBBBB
268 *
269 * Example:
270 * device at instance 0 and slot 8, minor device number 0x8 = decimal 8
271 * device at instance 1 and slot 10, minor device number 0x1A = decimal 26
272 */
273#define	SYSC_SLOT_MASK		0x0F
274#define	SYSC_INSTANCE_MASK	0xF0
275#define	SYSC_INSTANCE_SHIFT	4
276
277/* Macro definitions */
278#define	HOTPLUG_DISABLED_PROPERTY "hotplug-disabled"
279#define	GETSLOT(unit)		(getminor(unit) & SYSC_SLOT_MASK)
280#define	GETINSTANCE(unit) \
281	((getminor(unit) & SYSC_INSTANCE_MASK) >> SYSC_INSTANCE_SHIFT)
282#define	PUTINSTANCE(inst) \
283	(((inst) << SYSC_INSTANCE_SHIFT) & SYSC_INSTANCE_MASK)
284#define	GETSOFTC(i) \
285	((struct sysctrl_soft_state *)ddi_get_soft_state(sysctrlp, getminor(i)))
286
287/*
288 * Definition of sysctrl ioctls.
289 */
290#define	SYSC_IOC		('H'<<8)
291
292#define	SYSC_CFGA_CMD_GETSTATUS		(SYSC_IOC|68)
293#define	SYSC_CFGA_CMD_EJECT		(SYSC_IOC|69)
294#define	SYSC_CFGA_CMD_INSERT		(SYSC_IOC|70)
295#define	SYSC_CFGA_CMD_CONNECT		(SYSC_IOC|71)
296#define	SYSC_CFGA_CMD_DISCONNECT	(SYSC_IOC|72)
297#define	SYSC_CFGA_CMD_UNCONFIGURE	(SYSC_IOC|73)
298#define	SYSC_CFGA_CMD_CONFIGURE		(SYSC_IOC|74)
299#define	SYSC_CFGA_CMD_TEST		(SYSC_IOC|75)
300#define	SYSC_CFGA_CMD_TEST_SET_COND	(SYSC_IOC|76)
301#define	SYSC_CFGA_CMD_QUIESCE_TEST	(SYSC_IOC|77)
302
303#if defined(_KERNEL)
304
305#define	SPUR_TIMEOUT_USEC			(1 * MICROSEC)
306#define	SPUR_LONG_TIMEOUT_USEC			(5 * MICROSEC)
307#define	AC_TIMEOUT_USEC				(1 * MICROSEC)
308#define	PS_FAIL_TIMEOUT_USEC			(500 * (MICROSEC / MILLISEC))
309#define	PPS_FAN_TIMEOUT_USEC			(1 * MICROSEC)
310
311#define	BRD_INSERT_DELAY_USEC			(500 * (MICROSEC / MILLISEC))
312#define	BRD_INSERT_RETRY_USEC			(5 * MICROSEC)
313#define	BRD_REMOVE_TIMEOUT_USEC			(2 * MICROSEC)
314#define	BLINK_LED_TIMEOUT_USEC			(300 * (MICROSEC / MILLISEC))
315#define	KEYSWITCH_TIMEOUT_USEC			(1 * MICROSEC)
316
317#define	PS_INSUFFICIENT_COUNTDOWN_SEC		30
318
319/*
320 * how many ticks to wait to register the state change
321 * NOTE: ticks are measured in PS_FAIL_TIMEOUT_USEC clicks
322 */
323#define	PS_PRES_CHANGE_TICKS	1
324#define	PS_FROM_BOOT_TICKS	1
325#define	PS_FROM_UNKNOWN_TICKS	10
326#define	PS_POWER_COUNTDOWN_TICKS 60
327
328/* Note: this timeout needs to be longer than FAN_OK_TIMEOUT_USEC */
329#define	PS_P_FAN_FROM_UNKNOWN_TICKS 15
330
331#define	PS_FROM_OK_TICKS	1
332#define	PS_PCH_FROM_OK_TICKS	3
333#define	PS_FROM_FAIL_TICKS	4
334
335/* NOTE: these ticks are measured in PPS_FAN_TIMEOUT_USEC clicks */
336#define	PPS_FROM_FAIL_TICKS	7
337
338/*
339 * how many spurious interrupts to take during a SPUR_LONG_TIMEOUT_USEC
340 * before complaining
341 */
342#define	MAX_SPUR_COUNT		2
343
344/*
345 * Global driver structure which defines the presence and status of
346 * all board power supplies.
347 */
348struct ps_state {
349	int pctr;			/* tick counter for presense deglitch */
350	int dcctr;			/* tick counter for dc ok deglitch */
351	enum e_pres_state pshadow;	/* presense shadow state */
352	enum e_state dcshadow;		/* dc ok shadow state */
353};
354
355/*
356 * for sysctrl_thread_wakeup()
357 */
358#define	OVERTEMP_POLL	1
359#define	KEYSWITCH_POLL	2
360
361/*
362 * Structures used in the driver to manage the hardware
363 * XXX will need to add a nodeid
364 */
365struct sysctrl_soft_state {
366	dev_info_t *dip;		/* dev info of myself */
367	dev_info_t *pdip;		/* dev info of parent */
368	struct sysctrl_soft_state *next;
369	int mondo;			/* INO for this type of interrupt */
370	uchar_t nslots;			/* slots in this system (0-16) */
371
372	pnode_t options_nodeid;		/* for nvram powerfail-time */
373
374	ddi_iblock_cookie_t iblock;	/* High level interrupt cookie */
375	ddi_idevice_cookie_t idevice;	/* TODO - Do we need this? */
376	ddi_softintr_t spur_id;		/* when we get a spurious int... */
377	ddi_iblock_cookie_t spur_int_c;	/* spur int cookie */
378	ddi_softintr_t spur_high_id;	/* when we reenable disabled ints */
379	ddi_softintr_t spur_long_to_id;	/* long timeout softint */
380	ddi_softintr_t ac_fail_id;	/* ac fail softintr id */
381	ddi_softintr_t ac_fail_high_id;	/* ac fail re-enable softintr id */
382	ddi_softintr_t ps_fail_int_id;	/* ps fail from intr softintr id */
383	ddi_iblock_cookie_t ps_fail_c;	/* ps fail softintr cookie */
384	ddi_softintr_t ps_fail_poll_id;	/* ps fail from polling softintr */
385	ddi_softintr_t pps_fan_id;	/* pps fan fail softintr id */
386	ddi_softintr_t pps_fan_high_id;	/* pps fan re-enable softintr id */
387	ddi_softintr_t sbrd_pres_id;	/* sbrd softintr id */
388	ddi_softintr_t sbrd_gone_id;	/* sbrd removed softintr id */
389	ddi_softintr_t blink_led_id;	/* led blinker softint */
390	ddi_iblock_cookie_t sys_led_c;	/* mutex cookie for sys LED lock */
391
392	volatile uchar_t *clk_freq1;	/* Clock frequency reg. 1 */
393	volatile uchar_t *clk_freq2;	/* Clock frequency reg. 2 */
394	volatile uchar_t *status1;	/* System Status1 register */
395	volatile uchar_t *status2;	/* System Status2 register */
396	volatile uchar_t *ps_stat;	/* Power Supply Status register */
397	volatile uchar_t *ps_pres;	/* Power Supply Presence register */
398	volatile uchar_t *pppsr;	/* 2nd Power Supply Status register */
399	volatile uchar_t *temp_reg;	/* VA of temperature register */
400	volatile uchar_t *rcons_ctl;	/* VA of Remote console UART */
401	volatile uchar_t *clk_ver;	/* clock version register */
402
403	/* This mutex protects the following data */
404	/* NOTE: *csr should only be accessed from interrupt level */
405	kmutex_t csr_mutex;		/* locking for csr enable bits */
406	volatile uchar_t *csr;		/* System Control Register */
407	uchar_t pps_fan_saved;		/* cached pps fanfail state */
408	uchar_t saved_en_state;		/* spurious int cache */
409	int spur_count;			/* count multiple spurious ints */
410
411	/* This mutex protects the following data */
412	kmutex_t spur_int_lock;		/* lock spurious interrupt data */
413	timeout_id_t spur_timeout_id;	/* quiet the int timeout id */
414	timeout_id_t spur_long_timeout_id; /* spurious long timeout interval */
415
416	/* This mutex protects the following data */
417	kmutex_t ps_fail_lock;		/* low level lock */
418	struct ps_state ps_stats[SYS_PS_COUNT]; /* state struct for all ps */
419	enum power_state power_state;	/* redundant power state */
420	int power_countdown;		/* clicks until reboot */
421
422	/* This mutex protects the following data */
423	kmutex_t sys_led_lock;		/* low level lock */
424	int sys_led;			/* on (TRUE) or off (FALSE) */
425	int sys_fault;			/* on (TRUE) or off (FALSE) */
426
427	/* various elements protected by their inherent access patterns */
428	int pps_fan_external_state;	/* external state of the pps fans */
429	int pps_fan_state_count[SYS_PPS_FAN_COUNT]; /* fan state counter */
430	struct temp_stats tempstat;	/* in memory storage of temperature */
431	enum keyswitch_state key_shadow; /* external state of the key switch */
432
433	int enable_rcons_atboot;	/* enable remote console at boot */
434};
435
436/*
437 * Kstat structures used to contain data which is requested by user
438 * programs.
439 */
440struct sysctrl_kstat {
441	struct kstat_named	csr;		/* system control register */
442	struct kstat_named	status1;	/* system status 1 */
443	struct kstat_named	status2;	/* system status 2 */
444	struct kstat_named	clk_freq2;	/* Clock register 2 */
445	struct kstat_named	fan_status;	/* shadow status 2 for fans */
446	struct kstat_named	key_status;	/* shadow status for key */
447	struct kstat_named	power_state;	/* redundant power status */
448	struct kstat_named	clk_ver;	/* clock version register */
449};
450
451#define	SYSC_ERR_SET(pkt, err)	(pkt)->cmd_cfga.errtype = (err)
452
453/*
454 * Function prototype
455 */
456int sysc_policy_disconnect(struct sysctrl_soft_state *,
457				sysc_cfga_pkt_t *, sysc_cfga_stat_t *);
458int sysc_policy_connect(struct sysctrl_soft_state *,
459				sysc_cfga_pkt_t *, sysc_cfga_stat_t *);
460int sysc_policy_unconfigure(struct sysctrl_soft_state *,
461				sysc_cfga_pkt_t *, sysc_cfga_stat_t *);
462int sysc_policy_configure(struct sysctrl_soft_state *,
463				sysc_cfga_pkt_t *, sysc_cfga_stat_t *);
464
465void sysc_policy_update(void *softsp, sysc_cfga_stat_t *sc, sysc_evt_t event);
466
467extern void		sysctrl_suspend_prepare(void);
468extern int		sysctrl_suspend(sysc_cfga_pkt_t *);
469extern void		sysctrl_resume(sysc_cfga_pkt_t *);
470
471#endif /* _KERNEL */
472#endif /* _ASM */
473
474#ifdef	__cplusplus
475}
476#endif
477
478#endif	/* _SYS_SYSCTRL_H */
479