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