Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / mips / sibyte / dev / sbobio.c
blob42f227918c43fa2d48043a8f4b337c6cb97eeae9
1 /* $NetBSD: sbobio.c,v 1.17 2009/08/12 12:56:29 simonb Exp $ */
3 /*
4 * Copyright 2000, 2001
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
15 * the source file.
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: sbobio.c,v 1.17 2009/08/12 12:56:29 simonb Exp $");
38 #include <sys/param.h>
39 #include <sys/device.h>
40 #include <sys/systm.h>
42 #include <machine/locore.h>
43 #include <mips/sibyte/include/sb1250_int.h>
44 #include <mips/sibyte/include/sb1250_regs.h>
45 #include <mips/sibyte/include/sb1250_scd.h>
46 #include <mips/sibyte/include/zbbusvar.h>
47 #include <mips/sibyte/dev/sbobiovar.h>
49 #include "locators.h"
51 static int sbobio_match(struct device *, struct cfdata *, void *);
52 static void sbobio_attach(struct device *, struct device *, void *);
54 CFATTACH_DECL(sbobio, sizeof(struct device),
55 sbobio_match, sbobio_attach, NULL, NULL);
57 static int sbobio_print(void *, const char *);
58 static const char *sbobio_device_type_name(enum sbobio_device_type type);
61 * XXXsimonb:
62 * DUART register addresses seem to offset by 0x100 for some
63 * reason I can't fathom so we just can't use A_DUART for the
64 * address of the DUART. Eg,
65 * A_DUART_CHANREG(0, 0) = 0x0010060000
66 * and R_DUART_MODE_REG_1 = 0x100 (first reg in the duart)
67 * but the 1125/1250 manual says the DUART starts at
68 * 0x0010060100.
69 * We define our own R_DUART_REGBASE to R_DUART_MODE_REG_1
70 * so that we can use a symbolic name to refer to the start
71 * of the duart register space.
74 static const struct sbobio_attach_locs sb1250_rev1_sbobio_devs[] = {
75 { A_SMB_0,
76 { K_INT_SMB_0, -1 },
77 SBOBIO_DEVTYPE_SMBUS },
78 { A_SMB_1,
79 { K_INT_SMB_1, -1 },
80 SBOBIO_DEVTYPE_SMBUS },
81 { A_DUART_CHANREG(0, R_DUART_REGBASE),
82 { K_INT_UART_0, K_INT_UART_1 },
83 SBOBIO_DEVTYPE_DUART },
84 { A_SER_BASE_0,
85 { K_INT_SER_0, -1 },
86 SBOBIO_DEVTYPE_SYNCSERIAL },
87 { A_SER_BASE_1,
88 { K_INT_SER_1, -1 },
89 SBOBIO_DEVTYPE_SYNCSERIAL },
90 #if 0
91 { A_IO_EXT_BASE,
92 { -1, -1 },
93 SBOBIO_DEVTYPE_GBUS },
94 #endif
95 { A_MAC_BASE_0,
96 { K_INT_MAC_0, -1 },
97 SBOBIO_DEVTYPE_MAC },
98 { A_MAC_BASE_1,
99 { K_INT_MAC_1, -1 },
100 SBOBIO_DEVTYPE_MAC },
101 { A_MAC_BASE_2,
102 { K_INT_MAC_2, -1 },
103 SBOBIO_DEVTYPE_MAC },
105 static const int sb1250_rev1_sbobio_dev_count =
106 sizeof sb1250_rev1_sbobio_devs / sizeof sb1250_rev1_sbobio_devs[0];
108 static const struct sbobio_attach_locs sb1250_sbobio_devs[] = {
109 { A_SMB_0,
110 { K_INT_SMB_0, -1 },
111 SBOBIO_DEVTYPE_SMBUS },
112 { A_SMB_1,
113 { K_INT_SMB_1, -1 },
114 SBOBIO_DEVTYPE_SMBUS },
115 { A_DUART_CHANREG(0, R_DUART_REGBASE),
116 { K_INT_UART_0, K_INT_UART_1},
117 SBOBIO_DEVTYPE_DUART },
118 { A_SER_BASE_0,
119 { K_INT_SER_0, -1 },
120 SBOBIO_DEVTYPE_SYNCSERIAL },
121 { A_SER_BASE_1,
122 { K_INT_SER_1, -1 },
123 SBOBIO_DEVTYPE_SYNCSERIAL },
124 #if 0
125 { A_IO_EXT_BASE,
126 { -1, -1 },
127 SBOBIO_DEVTYPE_GBUS },
128 #endif
129 { A_MAC_BASE_0,
130 { K_INT_MAC_0, K_INT_MAC_0_CH1 },
131 SBOBIO_DEVTYPE_MAC },
132 { A_MAC_BASE_1,
133 { K_INT_MAC_1, K_INT_MAC_1_CH1 },
134 SBOBIO_DEVTYPE_MAC },
135 { A_MAC_BASE_2,
136 { K_INT_MAC_2, K_INT_MAC_2_CH1 },
137 SBOBIO_DEVTYPE_MAC },
139 static const int sb1250_sbobio_dev_count =
140 sizeof sb1250_sbobio_devs / sizeof sb1250_sbobio_devs[0];
142 static const struct sbobio_attach_locs sb112x_sbobio_devs[] = {
143 { A_SMB_0,
144 { K_INT_SMB_0, -1 },
145 SBOBIO_DEVTYPE_SMBUS },
146 { A_SMB_1,
147 { K_INT_SMB_1, -1 },
148 SBOBIO_DEVTYPE_SMBUS },
149 { A_DUART_CHANREG(0, R_DUART_REGBASE),
150 { K_INT_UART_0, K_INT_UART_1 },
151 SBOBIO_DEVTYPE_DUART },
152 { A_SER_BASE_0,
153 { K_INT_SER_0, -1 },
154 SBOBIO_DEVTYPE_SYNCSERIAL },
155 { A_SER_BASE_1,
156 { K_INT_SER_1, -1 },
157 SBOBIO_DEVTYPE_SYNCSERIAL },
158 #if 0
159 { A_IO_EXT_BASE,
160 { -1, -1 },
161 SBOBIO_DEVTYPE_GBUS },
162 #endif
163 { A_MAC_BASE_0,
164 { K_INT_MAC_0, K_INT_MAC_0_CH1 },
165 SBOBIO_DEVTYPE_MAC },
166 { A_MAC_BASE_1,
167 { K_INT_MAC_1, K_INT_MAC_1_CH1 },
168 SBOBIO_DEVTYPE_MAC },
170 static const int sb112x_sbobio_dev_count =
171 sizeof sb112x_sbobio_devs / sizeof sb112x_sbobio_devs[0];
173 static int
174 sbobio_match(struct device *parent, struct cfdata *match, void *aux)
176 struct zbbus_attach_args *zap = aux;
177 uint64_t sysrev;
179 if (zap->za_locs.za_type != ZBBUS_ENTTYPE_OBIO)
180 return (0);
182 sysrev = mips3_ld((volatile uint64_t *)MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION));
183 switch (SYS_SOC_TYPE(sysrev)) {
184 case K_SYS_SOC_TYPE_BCM1120:
185 case K_SYS_SOC_TYPE_BCM1125:
186 case K_SYS_SOC_TYPE_BCM1125H:
187 case K_SYS_SOC_TYPE_BCM1250:
188 break;
190 default:
191 return (0);
194 return (1);
197 static void
198 sbobio_attach(struct device *parent, struct device *self, void *aux)
200 struct sbobio_attach_args sa;
201 const char *dscr;
202 const struct sbobio_attach_locs *devs;
203 uint64_t sysrev;
204 int i, devcount;
205 int locs[SBOBIOCF_NLOCS];
207 sysrev = mips3_ld((volatile uint64_t *)MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION));
208 switch (SYS_SOC_TYPE(sysrev)) {
209 case K_SYS_SOC_TYPE_BCM1120:
210 case K_SYS_SOC_TYPE_BCM1125:
211 case K_SYS_SOC_TYPE_BCM1125H:
212 dscr = "BCM112x";
213 devs = sb112x_sbobio_devs;
214 devcount = sb112x_sbobio_dev_count;
215 break;
217 case K_SYS_SOC_TYPE_BCM1250:
218 if (G_SYS_REVISION(sysrev) >= K_SYS_REVISION_BCM1250_PASS2) {
219 dscr = "BCM1250 (rev2 and later)";
220 devs = sb1250_sbobio_devs;
221 devcount = sb1250_sbobio_dev_count;
222 } else {
223 dscr = "BCM1250 rev1";
224 devs = sb1250_rev1_sbobio_devs;
225 devcount = sb1250_rev1_sbobio_dev_count;
227 break;
228 default:
229 panic("un-matched in sbobio_attach");
230 break;
233 printf(": %s peripherals\n", dscr);
235 for (i = 0; i < devcount; i++) {
236 memset(&sa, 0, sizeof sa);
237 sa.sa_locs = devs[i];
239 locs[SBOBIOCF_ADDR] = devs[i].sa_addr;
240 locs[SBOBIOCF_INTR + 0] = devs[i].sa_intr[0];
241 locs[SBOBIOCF_INTR + 1] = devs[i].sa_intr[1];
243 config_found_sm_loc(self, "sbobio", locs, &sa,
244 sbobio_print, config_stdsubmatch);
246 return;
250 sbobio_print(void *aux, const char *pnp)
252 struct sbobio_attach_args *sap = aux;
253 int i;
255 if (pnp)
256 aprint_normal("%s at %s",
257 sbobio_device_type_name(sap->sa_locs.sa_type), pnp);
258 aprint_normal(" addr 0x%x", sap->sa_locs.sa_addr);
259 for (i = 0; i < 2; i++) {
260 if (sap->sa_locs.sa_intr[i] != SBOBIOCF_INTR_DEFAULT)
261 aprint_normal("%s%d", i == 0 ? " intr " : ",",
262 sap->sa_locs.sa_intr[i]);
264 return (UNCONF);
267 static const char *
268 sbobio_device_type_name(enum sbobio_device_type type)
271 switch (type) {
272 case SBOBIO_DEVTYPE_SMBUS:
273 return ("sbsmbus");
274 case SBOBIO_DEVTYPE_DUART:
275 return ("sbscn");
276 case SBOBIO_DEVTYPE_SYNCSERIAL:
277 return ("sbsync");
278 case SBOBIO_DEVTYPE_GBUS:
279 return ("sbgbus");
280 case SBOBIO_DEVTYPE_MAC:
281 return ("sbmac");
283 panic("sbobio_device_type_name");
284 return ("panic");