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