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, 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
     33 extern "C" {
     34 #endif
     35 
     36 /*
     37  * driver state type:
     38  */
     39 typedef 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  */
     56 typedef struct {
     57 	char *name;
     58 	uint_t inuse;
     59 	uint_t (*handler)();
     60 	caddr_t arg;
     61 } ebus_intr_slot_t;
     62 #endif
     63 
     64 struct 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 
     72 struct 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  */
     81 typedef 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 */
     88 struct 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 */
     98 struct 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 
    106 typedef union vrangespec {
    107 	struct ebus_pci_rangespec	pci_rangespec;
    108 	struct ebus_jbus_rangespec	jbus_rangespec;
    109 } vrangespec_t;
    110 
    111 typedef 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  */
    119 typedef 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));
    216 static void
    217 ebus_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