1 /* $NetBSD: sbgbus.c,v 1.10 2005/12/11 12:18:12 christos Exp $ */
5 * Broadcom Corporation. All rights reserved.
7 * This software is furnished under license and may be used and copied only
8 * in accordance with the following terms and conditions. Subject to these
9 * conditions, you may download, copy, install, use, modify and distribute
10 * modified or unmodified copies of this software in source and/or binary
11 * form. No title or ownership is transferred hereby.
13 * 1) Any source code used, modified or distributed must reproduce and
14 * retain this copyright notice and list of conditions as they appear in
17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Broadcom Corporation. The "Broadcom Corporation" name may not be
19 * used to endorse or promote products derived from this software
20 * without the prior written permission of Broadcom Corporation.
22 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
25 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
26 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
27 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: sbgbus.c,v 1.10 2005/12/11 12:18:12 christos Exp $");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
42 #include <machine/locore.h>
43 #include <machine/sb1250/sb1250_regs.h>
44 #include <machine/sb1250/sb1250_genbus.h>
45 #include <sbmips/dev/sbobio/sbobiovar.h>
46 #include <sbmips/dev/sbgbus/sbgbusvar.h>
48 extern struct cfdriver sbgbus_cd
;
50 static int sbgbus_match(struct device
*, struct cfdata
*, void *);
51 static void sbgbus_attach(struct device
*, struct device
*, void *);
53 CFATTACH_DECL(sbgbus
, sizeof(struct device
),
54 sbgbus_match
, sbgbus_attach
, NULL
, NULL
);
56 static int sbgbussearch(struct device
*, struct cfdata
*,
58 static int sbgbusprint(void *, const char *);
61 sbgbus_match(struct device
*parent
, struct cfdata
*match
, void *aux
)
63 struct sbobio_attach_args
*sap
= aux
;
65 if (sap
->sa_locs
.sa_type
!= SBOBIO_DEVTYPE_GBUS
)
72 sbgbus_attach(struct device
*parent
, struct device
*self
, void *aux
)
75 /* Configure children using indirect configuration. */
76 config_search_ia(sbgbussearch
, self
, "sbgbus", NULL
);
80 sbgbusprint(void *aux
, const char *pnp
)
82 struct sbgbus_attach_args
*sga
= aux
;
84 if (sga
->sga_chipsel
!= SBGBUS_CHIPSEL_NONE
)
85 aprint_normal(" chipsel %u", sga
->sga_chipsel
);
86 if (sga
->sga_offset
!= 0)
87 aprint_normal(" offset 0x%x", sga
->sga_offset
);
88 if (sga
->sga_intr
[0] != SBGBUS_INTR_NONE
) {
89 aprint_normal(" intr %u", sga
->sga_intr
[0]);
90 if (sga
->sga_intr
[1] != SBGBUS_INTR_NONE
) {
91 aprint_normal(",%u", sga
->sga_intr
[1]);
98 sbgbussearch(struct device
*parent
, struct cfdata
*cf
,
99 const int *ldesc
, void *aux
)
101 struct sbgbus_attach_args sga
;
106 sga
.sga_chipsel
= cf
->cf_loc
[SBGBUSCF_CHIPSEL
];
107 sga
.sga_offset
= cf
->cf_loc
[SBGBUSCF_OFFSET
];
108 sga
.sga_intr
[0] = cf
->cf_loc
[SBGBUSCF_INTR
];
109 sga
.sga_intr
[1] = cf
->cf_loc
[SBGBUSCF_INTR_1
];
111 /* Some quick sanity checks. */
112 if (sga
.sga_intr
[0] == SBGBUS_INTR_NONE
&&
113 sga
.sga_intr
[1] != SBGBUS_INTR_NONE
) {
114 /* XXX probably should print */
117 if (sga
.sga_chipsel
== SBGBUS_CHIPSEL_NONE
&&
118 sga
.sga_offset
!= 0) {
119 /* XXX probably should print */
122 if (sga
.sga_chipsel
>= IO_EXT_CFG_COUNT
) {
123 /* XXX probably should print */
127 /* XXX check for PCMCIA. */
129 if (sga
.sga_chipsel
== SBGBUS_CHIPSEL_NONE
) {
130 sga
.sga_startphys
= 0;
135 rv
= mips3_ld((volatile uint64_t *)MIPS_PHYS_TO_KSEG1(
136 A_IO_EXT_CS_BASE(sga
.sga_chipsel
) +
137 R_IO_EXT_START_ADDR
));
138 sga
.sga_startphys
= (rv
& M_IO_START_ADDR
) << S_IO_ADDRBASE
;
139 rv
= mips3_ld((volatile uint64_t *)MIPS_PHYS_TO_KSEG1(
140 A_IO_EXT_CS_BASE(sga
.sga_chipsel
) +
141 R_IO_EXT_MULT_SIZE
));
142 sga
.sga_size
= (rv
& M_IO_MULT_SIZE
) << S_IO_REGSIZE
;
144 /* Make sure that region is enabled. */
145 if (sga
.sga_size
== 0 ||
146 sga
.sga_startphys
< A_PHYS_GENBUS
||
147 sga
.sga_startphys
>= A_PHYS_GENBUS_END
)
150 /* Report to child only the space they can access. */
151 if (sga
.sga_startphys
+ sga
.sga_size
> A_PHYS_GENBUS_END
)
152 sga
.sga_size
= A_PHYS_GENBUS_END
- sga
.sga_startphys
;
156 if (config_match(parent
, cf
, &sga
) > 0) {
157 config_attach(parent
, cf
, &sga
, sbgbusprint
);
158 tryagain
= (cf
->cf_fstate
== FSTATE_STAR
);