1 1.25 thorpej /* $NetBSD: sbobio.c,v 1.25 2021/08/07 16:18:59 thorpej Exp $ */ 2 1.1 simonb 3 1.1 simonb /* 4 1.1 simonb * Copyright 2000, 2001 5 1.1 simonb * Broadcom Corporation. All rights reserved. 6 1.1 simonb * 7 1.1 simonb * This software is furnished under license and may be used and copied only 8 1.1 simonb * in accordance with the following terms and conditions. Subject to these 9 1.1 simonb * conditions, you may download, copy, install, use, modify and distribute 10 1.1 simonb * modified or unmodified copies of this software in source and/or binary 11 1.1 simonb * form. No title or ownership is transferred hereby. 12 1.1 simonb * 13 1.1 simonb * 1) Any source code used, modified or distributed must reproduce and 14 1.1 simonb * retain this copyright notice and list of conditions as they appear in 15 1.1 simonb * the source file. 16 1.1 simonb * 17 1.1 simonb * 2) No right is granted to use any trade name, trademark, or logo of 18 1.9 cgd * Broadcom Corporation. The "Broadcom Corporation" name may not be 19 1.9 cgd * used to endorse or promote products derived from this software 20 1.9 cgd * without the prior written permission of Broadcom Corporation. 21 1.1 simonb * 22 1.1 simonb * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 23 1.1 simonb * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 24 1.1 simonb * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 25 1.1 simonb * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 26 1.1 simonb * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 27 1.1 simonb * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 1.1 simonb * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 1.1 simonb * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 1.1 simonb * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 1.1 simonb * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 32 1.1 simonb * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 simonb */ 34 1.12 lukem 35 1.12 lukem #include <sys/cdefs.h> 36 1.25 thorpej __KERNEL_RCSID(0, "$NetBSD: sbobio.c,v 1.25 2021/08/07 16:18:59 thorpej Exp $"); 37 1.1 simonb 38 1.1 simonb #include <sys/param.h> 39 1.1 simonb #include <sys/device.h> 40 1.1 simonb #include <sys/systm.h> 41 1.1 simonb 42 1.22 matt #include <mips/locore.h> 43 1.22 matt 44 1.17 simonb #include <mips/sibyte/include/sb1250_int.h> 45 1.2 simonb #include <mips/sibyte/include/sb1250_regs.h> 46 1.7 cgd #include <mips/sibyte/include/sb1250_scd.h> 47 1.1 simonb #include <mips/sibyte/include/zbbusvar.h> 48 1.1 simonb #include <mips/sibyte/dev/sbobiovar.h> 49 1.1 simonb 50 1.1 simonb #include "locators.h" 51 1.1 simonb 52 1.19 matt static int sbobio_match(device_t, cfdata_t, void *); 53 1.19 matt static void sbobio_attach(device_t, device_t, void *); 54 1.1 simonb 55 1.19 matt CFATTACH_DECL_NEW(sbobio, 0, 56 1.6 thorpej sbobio_match, sbobio_attach, NULL, NULL); 57 1.1 simonb 58 1.1 simonb static int sbobio_print(void *, const char *); 59 1.1 simonb static const char *sbobio_device_type_name(enum sbobio_device_type type); 60 1.1 simonb 61 1.17 simonb /* 62 1.17 simonb * XXXsimonb: 63 1.17 simonb * DUART register addresses seem to offset by 0x100 for some 64 1.17 simonb * reason I can't fathom so we just can't use A_DUART for the 65 1.17 simonb * address of the DUART. Eg, 66 1.17 simonb * A_DUART_CHANREG(0, 0) = 0x0010060000 67 1.17 simonb * and R_DUART_MODE_REG_1 = 0x100 (first reg in the duart) 68 1.17 simonb * but the 1125/1250 manual says the DUART starts at 69 1.17 simonb * 0x0010060100. 70 1.17 simonb * We define our own R_DUART_REGBASE to R_DUART_MODE_REG_1 71 1.17 simonb * so that we can use a symbolic name to refer to the start 72 1.17 simonb * of the duart register space. 73 1.17 simonb */ 74 1.17 simonb 75 1.7 cgd static const struct sbobio_attach_locs sb1250_rev1_sbobio_devs[] = { 76 1.17 simonb { A_SMB_0, 77 1.17 simonb { K_INT_SMB_0, -1 }, 78 1.17 simonb SBOBIO_DEVTYPE_SMBUS }, 79 1.17 simonb { A_SMB_1, 80 1.17 simonb { K_INT_SMB_1, -1 }, 81 1.17 simonb SBOBIO_DEVTYPE_SMBUS }, 82 1.17 simonb { A_DUART_CHANREG(0, R_DUART_REGBASE), 83 1.17 simonb { K_INT_UART_0, K_INT_UART_1 }, 84 1.17 simonb SBOBIO_DEVTYPE_DUART }, 85 1.17 simonb { A_SER_BASE_0, 86 1.17 simonb { K_INT_SER_0, -1 }, 87 1.17 simonb SBOBIO_DEVTYPE_SYNCSERIAL }, 88 1.17 simonb { A_SER_BASE_1, 89 1.17 simonb { K_INT_SER_1, -1 }, 90 1.17 simonb SBOBIO_DEVTYPE_SYNCSERIAL }, 91 1.1 simonb #if 0 92 1.17 simonb { A_IO_EXT_BASE, 93 1.17 simonb { -1, -1 }, 94 1.17 simonb SBOBIO_DEVTYPE_GBUS }, 95 1.1 simonb #endif 96 1.17 simonb { A_MAC_BASE_0, 97 1.17 simonb { K_INT_MAC_0, -1 }, 98 1.17 simonb SBOBIO_DEVTYPE_MAC }, 99 1.17 simonb { A_MAC_BASE_1, 100 1.17 simonb { K_INT_MAC_1, -1 }, 101 1.17 simonb SBOBIO_DEVTYPE_MAC }, 102 1.17 simonb { A_MAC_BASE_2, 103 1.17 simonb { K_INT_MAC_2, -1 }, 104 1.17 simonb SBOBIO_DEVTYPE_MAC }, 105 1.1 simonb }; 106 1.7 cgd static const int sb1250_rev1_sbobio_dev_count = 107 1.7 cgd sizeof sb1250_rev1_sbobio_devs / sizeof sb1250_rev1_sbobio_devs[0]; 108 1.7 cgd 109 1.7 cgd static const struct sbobio_attach_locs sb1250_sbobio_devs[] = { 110 1.17 simonb { A_SMB_0, 111 1.17 simonb { K_INT_SMB_0, -1 }, 112 1.17 simonb SBOBIO_DEVTYPE_SMBUS }, 113 1.17 simonb { A_SMB_1, 114 1.17 simonb { K_INT_SMB_1, -1 }, 115 1.17 simonb SBOBIO_DEVTYPE_SMBUS }, 116 1.17 simonb { A_DUART_CHANREG(0, R_DUART_REGBASE), 117 1.17 simonb { K_INT_UART_0, K_INT_UART_1}, 118 1.17 simonb SBOBIO_DEVTYPE_DUART }, 119 1.17 simonb { A_SER_BASE_0, 120 1.17 simonb { K_INT_SER_0, -1 }, 121 1.17 simonb SBOBIO_DEVTYPE_SYNCSERIAL }, 122 1.17 simonb { A_SER_BASE_1, 123 1.17 simonb { K_INT_SER_1, -1 }, 124 1.17 simonb SBOBIO_DEVTYPE_SYNCSERIAL }, 125 1.7 cgd #if 0 126 1.17 simonb { A_IO_EXT_BASE, 127 1.17 simonb { -1, -1 }, 128 1.17 simonb SBOBIO_DEVTYPE_GBUS }, 129 1.7 cgd #endif 130 1.17 simonb { A_MAC_BASE_0, 131 1.17 simonb { K_INT_MAC_0, K_INT_MAC_0_CH1 }, 132 1.17 simonb SBOBIO_DEVTYPE_MAC }, 133 1.17 simonb { A_MAC_BASE_1, 134 1.17 simonb { K_INT_MAC_1, K_INT_MAC_1_CH1 }, 135 1.17 simonb SBOBIO_DEVTYPE_MAC }, 136 1.17 simonb { A_MAC_BASE_2, 137 1.17 simonb { K_INT_MAC_2, K_INT_MAC_2_CH1 }, 138 1.17 simonb SBOBIO_DEVTYPE_MAC }, 139 1.7 cgd }; 140 1.1 simonb static const int sb1250_sbobio_dev_count = 141 1.1 simonb sizeof sb1250_sbobio_devs / sizeof sb1250_sbobio_devs[0]; 142 1.1 simonb 143 1.7 cgd static const struct sbobio_attach_locs sb112x_sbobio_devs[] = { 144 1.17 simonb { A_SMB_0, 145 1.17 simonb { K_INT_SMB_0, -1 }, 146 1.17 simonb SBOBIO_DEVTYPE_SMBUS }, 147 1.17 simonb { A_SMB_1, 148 1.17 simonb { K_INT_SMB_1, -1 }, 149 1.17 simonb SBOBIO_DEVTYPE_SMBUS }, 150 1.17 simonb { A_DUART_CHANREG(0, R_DUART_REGBASE), 151 1.17 simonb { K_INT_UART_0, K_INT_UART_1 }, 152 1.17 simonb SBOBIO_DEVTYPE_DUART }, 153 1.17 simonb { A_SER_BASE_0, 154 1.17 simonb { K_INT_SER_0, -1 }, 155 1.17 simonb SBOBIO_DEVTYPE_SYNCSERIAL }, 156 1.17 simonb { A_SER_BASE_1, 157 1.17 simonb { K_INT_SER_1, -1 }, 158 1.17 simonb SBOBIO_DEVTYPE_SYNCSERIAL }, 159 1.7 cgd #if 0 160 1.17 simonb { A_IO_EXT_BASE, 161 1.17 simonb { -1, -1 }, 162 1.17 simonb SBOBIO_DEVTYPE_GBUS }, 163 1.7 cgd #endif 164 1.17 simonb { A_MAC_BASE_0, 165 1.17 simonb { K_INT_MAC_0, K_INT_MAC_0_CH1 }, 166 1.17 simonb SBOBIO_DEVTYPE_MAC }, 167 1.17 simonb { A_MAC_BASE_1, 168 1.17 simonb { K_INT_MAC_1, K_INT_MAC_1_CH1 }, 169 1.17 simonb SBOBIO_DEVTYPE_MAC }, 170 1.7 cgd }; 171 1.7 cgd static const int sb112x_sbobio_dev_count = 172 1.7 cgd sizeof sb112x_sbobio_devs / sizeof sb112x_sbobio_devs[0]; 173 1.7 cgd 174 1.1 simonb static int 175 1.19 matt sbobio_match(device_t parent, cfdata_t match, void *aux) 176 1.1 simonb { 177 1.1 simonb struct zbbus_attach_args *zap = aux; 178 1.7 cgd uint64_t sysrev; 179 1.1 simonb 180 1.1 simonb if (zap->za_locs.za_type != ZBBUS_ENTTYPE_OBIO) 181 1.1 simonb return (0); 182 1.1 simonb 183 1.23 christos sysrev = mips3_ld((register_t)MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION)); 184 1.7 cgd switch (SYS_SOC_TYPE(sysrev)) { 185 1.7 cgd case K_SYS_SOC_TYPE_BCM1120: 186 1.7 cgd case K_SYS_SOC_TYPE_BCM1125: 187 1.7 cgd case K_SYS_SOC_TYPE_BCM1125H: 188 1.7 cgd case K_SYS_SOC_TYPE_BCM1250: 189 1.7 cgd break; 190 1.7 cgd 191 1.7 cgd default: 192 1.10 simonb return (0); 193 1.7 cgd } 194 1.7 cgd 195 1.10 simonb return (1); 196 1.1 simonb } 197 1.1 simonb 198 1.1 simonb static void 199 1.19 matt sbobio_attach(device_t parent, device_t self, void *aux) 200 1.1 simonb { 201 1.1 simonb struct sbobio_attach_args sa; 202 1.7 cgd const char *dscr; 203 1.7 cgd const struct sbobio_attach_locs *devs; 204 1.7 cgd uint64_t sysrev; 205 1.7 cgd int i, devcount; 206 1.14 drochner int locs[SBOBIOCF_NLOCS]; 207 1.7 cgd 208 1.23 christos sysrev = mips3_ld((register_t)MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION)); 209 1.7 cgd switch (SYS_SOC_TYPE(sysrev)) { 210 1.7 cgd case K_SYS_SOC_TYPE_BCM1120: 211 1.7 cgd case K_SYS_SOC_TYPE_BCM1125: 212 1.7 cgd case K_SYS_SOC_TYPE_BCM1125H: 213 1.7 cgd dscr = "BCM112x"; 214 1.7 cgd devs = sb112x_sbobio_devs; 215 1.7 cgd devcount = sb112x_sbobio_dev_count; 216 1.7 cgd break; 217 1.7 cgd 218 1.7 cgd case K_SYS_SOC_TYPE_BCM1250: 219 1.7 cgd if (G_SYS_REVISION(sysrev) >= K_SYS_REVISION_BCM1250_PASS2) { 220 1.7 cgd dscr = "BCM1250 (rev2 and later)"; 221 1.7 cgd devs = sb1250_sbobio_devs; 222 1.7 cgd devcount = sb1250_sbobio_dev_count; 223 1.7 cgd } else { 224 1.7 cgd dscr = "BCM1250 rev1"; 225 1.7 cgd devs = sb1250_rev1_sbobio_devs; 226 1.7 cgd devcount = sb1250_rev1_sbobio_dev_count; 227 1.7 cgd } 228 1.7 cgd break; 229 1.7 cgd default: 230 1.7 cgd panic("un-matched in sbobio_attach"); 231 1.7 cgd break; 232 1.7 cgd } 233 1.1 simonb 234 1.20 matt aprint_normal(": %s peripherals\n", dscr); 235 1.1 simonb 236 1.7 cgd for (i = 0; i < devcount; i++) { 237 1.1 simonb memset(&sa, 0, sizeof sa); 238 1.7 cgd sa.sa_locs = devs[i]; 239 1.13 drochner 240 1.21 matt locs[SBOBIOCF_OFFSET] = devs[i].sa_offset; 241 1.14 drochner locs[SBOBIOCF_INTR + 0] = devs[i].sa_intr[0]; 242 1.14 drochner locs[SBOBIOCF_INTR + 1] = devs[i].sa_intr[1]; 243 1.13 drochner 244 1.24 thorpej config_found(self, &sa, sbobio_print, 245 1.25 thorpej CFARGS(.submatch = config_stdsubmatch, 246 1.25 thorpej .locators = locs)); 247 1.1 simonb } 248 1.1 simonb return; 249 1.1 simonb } 250 1.1 simonb 251 1.1 simonb int 252 1.1 simonb sbobio_print(void *aux, const char *pnp) 253 1.1 simonb { 254 1.1 simonb struct sbobio_attach_args *sap = aux; 255 1.1 simonb int i; 256 1.1 simonb 257 1.1 simonb if (pnp) 258 1.8 thorpej aprint_normal("%s at %s", 259 1.1 simonb sbobio_device_type_name(sap->sa_locs.sa_type), pnp); 260 1.21 matt aprint_normal(" offset 0x%lx", sap->sa_locs.sa_offset); 261 1.1 simonb for (i = 0; i < 2; i++) { 262 1.2 simonb if (sap->sa_locs.sa_intr[i] != SBOBIOCF_INTR_DEFAULT) 263 1.17 simonb aprint_normal("%s%d", i == 0 ? " intr " : ",", 264 1.17 simonb sap->sa_locs.sa_intr[i]); 265 1.1 simonb } 266 1.1 simonb return (UNCONF); 267 1.1 simonb } 268 1.1 simonb 269 1.1 simonb static const char * 270 1.1 simonb sbobio_device_type_name(enum sbobio_device_type type) 271 1.1 simonb { 272 1.1 simonb 273 1.1 simonb switch (type) { 274 1.1 simonb case SBOBIO_DEVTYPE_SMBUS: 275 1.1 simonb return ("sbsmbus"); 276 1.1 simonb case SBOBIO_DEVTYPE_DUART: 277 1.1 simonb return ("sbscn"); 278 1.1 simonb case SBOBIO_DEVTYPE_SYNCSERIAL: 279 1.1 simonb return ("sbsync"); 280 1.1 simonb case SBOBIO_DEVTYPE_GBUS: 281 1.1 simonb return ("sbgbus"); 282 1.1 simonb case SBOBIO_DEVTYPE_MAC: 283 1.1 simonb return ("sbmac"); 284 1.1 simonb } 285 1.1 simonb panic("sbobio_device_type_name"); 286 1.1 simonb return ("panic"); 287 1.1 simonb } 288