xref: /illumos-gate/usr/src/uts/sun4/sys/ebus.h (revision fcdb3229a31dd4ff700c69238814e326aad49098)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_EBUS_H
28 #define	_SYS_EBUS_H
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 /*
35  * driver state type:
36  */
37 typedef enum { NEW = 0, ATTACHED, RESUMED, DETACHED,
38 		SUSPENDED, PM_SUSPENDED } driver_state_t;
39 
40 /*
41  * The i86pc specific code fragments are to support the debug of "honeynut"
42  * and "multigrain" prototypes on i86pc platform.  Most of the fragments
43  * deal with differences in the interrupt dispatching between the prototypes
44  * and the cheerio ebus.  On the prototype boards, all interrupt lines are
45  * tied together.  For this case, the nexus driver uses a common interrupt
46  * handler to poll all of its children.
47  */
48 #if defined(i86pc)
49 #define	MAX_EBUS_DEVS	6
50 
51 /*
52  * ebus device interrupt info;
53  */
54 typedef struct {
55 	char *name;
56 	uint_t inuse;
57 	uint_t (*handler)();
58 	caddr_t arg;
59 } ebus_intr_slot_t;
60 #endif
61 
62 struct ebus_intr_map {
63 	uint32_t ebus_phys_hi;
64 	uint32_t ebus_phys_low;
65 	uint32_t ebus_intr;
66 	uint32_t intr_ctlr_nodeid;
67 	uint32_t ino;
68 };
69 
70 struct ebus_intr_map_mask {
71 	uint32_t ebus_phys_hi;
72 	uint32_t ebus_phys_low;
73 	uint32_t ebus_intr;
74 };
75 
76 /*
77  * definition of ebus reg spec entry:
78  */
79 typedef struct {
80 	uint32_t addr_hi;
81 	uint32_t addr_low;
82 	uint32_t size;
83 } ebus_regspec_t;
84 
85 /* Range entry for 3-cell parent address */
86 struct ebus_pci_rangespec {
87 	uint32_t phys_hi;			/* Child hi range address */
88 	uint32_t phys_low;			/* Child low range address */
89 	uint32_t par_phys_hi;			/* Parent hi rng addr */
90 	uint32_t par_phys_mid;			/* Parent mid rng addr */
91 	uint32_t par_phys_low;			/* Parent low rng addr */
92 	uint32_t rng_size;			/* Range size */
93 };
94 
95 /* Range entry for 2-cell parent address */
96 struct ebus_jbus_rangespec {
97 	uint32_t phys_hi;			/* Child hi range address */
98 	uint32_t phys_low;			/* Child low range address */
99 	uint32_t par_phys_hi;			/* Parent hi rng addr */
100 	uint32_t par_phys_low;			/* Parent low rng addr */
101 	uint32_t rng_size;			/* Range size */
102 };
103 
104 typedef union vrangespec {
105 	struct ebus_pci_rangespec	pci_rangespec;
106 	struct ebus_jbus_rangespec	jbus_rangespec;
107 } vrangespec_t;
108 
109 typedef union vregspec {
110 	struct pci_phys_spec	pci_regspec;
111 	struct regspec		jbus_regspec;
112 } vregspec_t;
113 
114 /*
115  * driver soft state structure:
116  */
117 typedef struct {
118 	dev_info_t *dip;
119 	driver_state_t state;
120 	pci_regspec_t *reg;
121 	int nreg;
122 
123 	vrangespec_t *vrangep;
124 	int vrange_len;
125 	int vrange_cnt;
126 
127 	kmutex_t ebus_mutex;
128 	uint_t ebus_soft_state;
129 #define	EBUS_SOFT_STATE_CLOSED		0x00
130 #define	EBUS_SOFT_STATE_OPEN		0x01
131 #define	EBUS_SOFT_STATE_OPEN_EXCL	0x02
132 
133 #if defined(i86pc)
134 	ddi_iblock_cookie_t iblock;
135 	ddi_idevice_cookie_t idevice;
136 	ebus_intr_slot_t intr_slot[MAX_EBUS_DEVS];
137 #endif
138 #if defined(__sparc)
139 	/* Interrupt support */
140 	int intr_map_size;
141 	struct ebus_intr_map *intr_map;
142 	struct ebus_intr_map_mask *intr_map_mask;
143 #endif
144 	int ebus_addr_cells;
145 	int ebus_paddr_cells;
146 	int ebus_psz_cells;
147 	int ebus_sz_cells;
148 } ebus_devstate_t;
149 
150 
151 /*
152  * use macros for soft state and driver properties:
153  */
154 #define	get_ebus_soft_state(i)	\
155 	((ebus_devstate_t *)ddi_get_soft_state(per_ebus_state, (i)))
156 
157 #define	alloc_ebus_soft_state(i)	\
158 	ddi_soft_state_zalloc(per_ebus_state, (i))
159 
160 #define	free_ebus_soft_state(i)	\
161 	ddi_soft_state_free(per_ebus_state, (i))
162 
163 
164 #define	getprop(dip, name, addr, intp)		\
165 		ddi_getlongprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
166 				(name), (caddr_t)(addr), (intp))
167 
168 #define	IS_RIO(dip) \
169 		((ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, \
170 		"device-id", -1) == 0x1100) && \
171 		(ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, \
172 		"vendor-id", -1) == 0x108e))
173 
174 #define	EBUS_4MHZ	4000
175 
176 /*
177  * register offsets and lengths:
178  */
179 #define	TCR_OFFSET	0x710000
180 #define	TCR_LENGTH	12
181 
182 /*
183  * timing control register settings:
184  */
185 #define	TCR1		0x08101008
186 #define	TCR2		0x08100020
187 #define	TCR3		0x00000020
188 
189 #if defined(DEBUG)
190 #define	D_IDENTIFY	0x00000001
191 #define	D_ATTACH	0x00000002
192 #define	D_DETACH	0x00000004
193 #define	D_MAP		0x00000008
194 #define	D_CTLOPS	0x00000010
195 #define	D_INTR		0x00000100
196 
197 #define	DBG(flag, psp, fmt)	\
198 	ebus_debug(flag, psp, fmt, 0, 0, 0, 0, 0);
199 #define	DBG1(flag, psp, fmt, a1)	\
200 	ebus_debug(flag, psp, fmt, (uintptr_t)(a1), 0, 0, 0, 0);
201 #define	DBG2(flag, psp, fmt, a1, a2)	\
202 	ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
203 #define	DBG3(flag, psp, fmt, a1, a2, a3)	\
204 	ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
205 	    (uintptr_t)(a3), 0, 0);
206 #define	DBG4(flag, psp, fmt, a1, a2, a3, a4)	\
207 	ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
208 	    (uintptr_t)(a3), \
209 		(uintptr_t)(a4), 0);
210 #define	DBG5(flag, psp, fmt, a1, a2, a3, a4, a5)	\
211 	ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
212 	    (uintptr_t)(a3), \
213 		(uintptr_t)(a4), (uintptr_t)(a5));
214 static void
215 ebus_debug(uint_t, ebus_devstate_t *, char *, uintptr_t, uintptr_t, uintptr_t,
216     uintptr_t, uintptr_t);
217 #else
218 #define	DBG(flag, psp, fmt)
219 #define	DBG1(flag, psp, fmt, a1)
220 #define	DBG2(flag, psp, fmt, a1, a2)
221 #define	DBG3(flag, psp, fmt, a1, a2, a3)
222 #define	DBG4(flag, psp, fmt, a1, a2, a3, a4)
223 #define	DBG5(flag, psp, fmt, a1, a2, a3, a4, a5)
224 #endif
225 
226 #ifdef	__cplusplus
227 }
228 #endif
229 
230 #endif	/* _SYS_EBUS_H */
231