1 /* $NetBSD: sbobio.c,v 1.17 2009/08/12 12:56:29 simonb 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: 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>
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
);
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
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
[] = {
77 SBOBIO_DEVTYPE_SMBUS
},
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
},
86 SBOBIO_DEVTYPE_SYNCSERIAL
},
89 SBOBIO_DEVTYPE_SYNCSERIAL
},
93 SBOBIO_DEVTYPE_GBUS
},
100 SBOBIO_DEVTYPE_MAC
},
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
[] = {
111 SBOBIO_DEVTYPE_SMBUS
},
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
},
120 SBOBIO_DEVTYPE_SYNCSERIAL
},
123 SBOBIO_DEVTYPE_SYNCSERIAL
},
127 SBOBIO_DEVTYPE_GBUS
},
130 { K_INT_MAC_0
, K_INT_MAC_0_CH1
},
131 SBOBIO_DEVTYPE_MAC
},
133 { K_INT_MAC_1
, K_INT_MAC_1_CH1
},
134 SBOBIO_DEVTYPE_MAC
},
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
[] = {
145 SBOBIO_DEVTYPE_SMBUS
},
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
},
154 SBOBIO_DEVTYPE_SYNCSERIAL
},
157 SBOBIO_DEVTYPE_SYNCSERIAL
},
161 SBOBIO_DEVTYPE_GBUS
},
164 { K_INT_MAC_0
, K_INT_MAC_0_CH1
},
165 SBOBIO_DEVTYPE_MAC
},
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];
174 sbobio_match(struct device
*parent
, struct cfdata
*match
, void *aux
)
176 struct zbbus_attach_args
*zap
= aux
;
179 if (zap
->za_locs
.za_type
!= ZBBUS_ENTTYPE_OBIO
)
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
:
198 sbobio_attach(struct device
*parent
, struct device
*self
, void *aux
)
200 struct sbobio_attach_args sa
;
202 const struct sbobio_attach_locs
*devs
;
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
:
213 devs
= sb112x_sbobio_devs
;
214 devcount
= sb112x_sbobio_dev_count
;
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
;
223 dscr
= "BCM1250 rev1";
224 devs
= sb1250_rev1_sbobio_devs
;
225 devcount
= sb1250_rev1_sbobio_dev_count
;
229 panic("un-matched in sbobio_attach");
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
);
250 sbobio_print(void *aux
, const char *pnp
)
252 struct sbobio_attach_args
*sap
= aux
;
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
]);
268 sbobio_device_type_name(enum sbobio_device_type type
)
272 case SBOBIO_DEVTYPE_SMBUS
:
274 case SBOBIO_DEVTYPE_DUART
:
276 case SBOBIO_DEVTYPE_SYNCSERIAL
:
278 case SBOBIO_DEVTYPE_GBUS
:
280 case SBOBIO_DEVTYPE_MAC
:
283 panic("sbobio_device_type_name");