1 /* $NetBSD: sbobio.c,v 1.16 2005/11/11 06:27:09 simonb 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.16 2005/11/11 06:27:09 simonb Exp $"); 37 38 #include <sys/param.h> 39 #include <sys/device.h> 40 #include <sys/systm.h> 41 42 #include <machine/locore.h> 43 #include <mips/sibyte/include/sb1250_regs.h> 44 #include <mips/sibyte/include/sb1250_scd.h> 45 #include <mips/sibyte/include/zbbusvar.h> 46 #include <mips/sibyte/dev/sbobiovar.h> 47 48 #include "locators.h" 49 50 static int sbobio_match(struct device *, struct cfdata *, void *); 51 static void sbobio_attach(struct device *, struct device *, void *); 52 53 CFATTACH_DECL(sbobio, sizeof(struct device), 54 sbobio_match, sbobio_attach, NULL, NULL); 55 56 static int sbobio_print(void *, const char *); 57 static const char *sbobio_device_type_name(enum sbobio_device_type type); 58 59 static const struct sbobio_attach_locs sb1250_rev1_sbobio_devs[] = { 60 { 0x0000, {6,-1}, SBOBIO_DEVTYPE_SMBUS }, 61 { 0x0008, {7,-1}, SBOBIO_DEVTYPE_SMBUS }, 62 { 0x0100, {8,9}, SBOBIO_DEVTYPE_DUART }, 63 { 0x0400, {10,-1}, SBOBIO_DEVTYPE_SYNCSERIAL }, 64 { 0x0800, {11,-1}, SBOBIO_DEVTYPE_SYNCSERIAL }, 65 #if 0 66 { 0x1000, {-1,-1}, SBOBIO_DEVTYPE_GBUS, }, /* XXXCGD ??? */ 67 #endif 68 { 0x4000, {19,-1}, SBOBIO_DEVTYPE_MAC, }, 69 { 0x5000, {20,-1}, SBOBIO_DEVTYPE_MAC, }, 70 { 0x6000, {21,-1}, SBOBIO_DEVTYPE_MAC, }, 71 }; 72 static const int sb1250_rev1_sbobio_dev_count = 73 sizeof sb1250_rev1_sbobio_devs / sizeof sb1250_rev1_sbobio_devs[0]; 74 75 static const struct sbobio_attach_locs sb1250_sbobio_devs[] = { 76 { 0x0000, {6,-1}, SBOBIO_DEVTYPE_SMBUS }, 77 { 0x0008, {7,-1}, SBOBIO_DEVTYPE_SMBUS }, 78 { 0x0100, {8,9}, SBOBIO_DEVTYPE_DUART }, 79 { 0x0400, {10,-1}, SBOBIO_DEVTYPE_SYNCSERIAL }, 80 { 0x0800, {11,-1}, SBOBIO_DEVTYPE_SYNCSERIAL }, 81 #if 0 82 { 0x1000, {-1,-1}, SBOBIO_DEVTYPE_GBUS, }, /* XXXCGD ??? */ 83 #endif 84 { 0x4000, {19,61}, SBOBIO_DEVTYPE_MAC, }, 85 { 0x5000, {20,62}, SBOBIO_DEVTYPE_MAC, }, 86 { 0x6000, {21,63}, SBOBIO_DEVTYPE_MAC, }, 87 }; 88 static const int sb1250_sbobio_dev_count = 89 sizeof sb1250_sbobio_devs / sizeof sb1250_sbobio_devs[0]; 90 91 static const struct sbobio_attach_locs sb112x_sbobio_devs[] = { 92 { 0x0000, {6,-1}, SBOBIO_DEVTYPE_SMBUS }, 93 { 0x0008, {7,-1}, SBOBIO_DEVTYPE_SMBUS }, 94 { 0x0100, {8,9}, SBOBIO_DEVTYPE_DUART }, 95 { 0x0400, {10,-1}, SBOBIO_DEVTYPE_SYNCSERIAL }, 96 { 0x0800, {11,-1}, SBOBIO_DEVTYPE_SYNCSERIAL }, 97 #if 0 98 { 0x1000, {-1,-1}, SBOBIO_DEVTYPE_GBUS, }, /* XXXCGD ??? */ 99 #endif 100 { 0x4000, {19,61}, SBOBIO_DEVTYPE_MAC, }, 101 { 0x5000, {20,62}, SBOBIO_DEVTYPE_MAC, }, 102 }; 103 static const int sb112x_sbobio_dev_count = 104 sizeof sb112x_sbobio_devs / sizeof sb112x_sbobio_devs[0]; 105 106 static int 107 sbobio_match(struct device *parent, struct cfdata *match, void *aux) 108 { 109 struct zbbus_attach_args *zap = aux; 110 uint64_t sysrev; 111 112 if (zap->za_locs.za_type != ZBBUS_ENTTYPE_OBIO) 113 return (0); 114 115 sysrev = mips3_ld((u_int64_t *)MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION)); 116 switch (SYS_SOC_TYPE(sysrev)) { 117 case K_SYS_SOC_TYPE_BCM1120: 118 case K_SYS_SOC_TYPE_BCM1125: 119 case K_SYS_SOC_TYPE_BCM1125H: 120 case K_SYS_SOC_TYPE_BCM1250: 121 break; 122 123 default: 124 return (0); 125 } 126 127 return (1); 128 } 129 130 static void 131 sbobio_attach(struct device *parent, struct device *self, void *aux) 132 { 133 struct sbobio_attach_args sa; 134 const char *dscr; 135 const struct sbobio_attach_locs *devs; 136 uint64_t sysrev; 137 int i, devcount; 138 int locs[SBOBIOCF_NLOCS]; 139 140 sysrev = mips3_ld((u_int64_t *)MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION)); 141 switch (SYS_SOC_TYPE(sysrev)) { 142 case K_SYS_SOC_TYPE_BCM1120: 143 case K_SYS_SOC_TYPE_BCM1125: 144 case K_SYS_SOC_TYPE_BCM1125H: 145 dscr = "BCM112x"; 146 devs = sb112x_sbobio_devs; 147 devcount = sb112x_sbobio_dev_count; 148 break; 149 150 case K_SYS_SOC_TYPE_BCM1250: 151 if (G_SYS_REVISION(sysrev) >= K_SYS_REVISION_BCM1250_PASS2) { 152 dscr = "BCM1250 (rev2 and later)"; 153 devs = sb1250_sbobio_devs; 154 devcount = sb1250_sbobio_dev_count; 155 } else { 156 dscr = "BCM1250 rev1"; 157 devs = sb1250_rev1_sbobio_devs; 158 devcount = sb1250_rev1_sbobio_dev_count; 159 } 160 break; 161 default: 162 panic("un-matched in sbobio_attach"); 163 break; 164 } 165 166 printf(": %s peripherals\n", dscr); 167 168 for (i = 0; i < devcount; i++) { 169 memset(&sa, 0, sizeof sa); 170 sa.sa_base = A_PHYS_IO_SYSTEM; 171 sa.sa_locs = devs[i]; 172 173 locs[SBOBIOCF_OFFSET] = devs[i].sa_offset; 174 locs[SBOBIOCF_INTR + 0] = devs[i].sa_intr[0]; 175 locs[SBOBIOCF_INTR + 1] = devs[i].sa_intr[1]; 176 177 config_found_sm_loc(self, "sbobio", locs, &sa, 178 sbobio_print, config_stdsubmatch); 179 } 180 return; 181 } 182 183 int 184 sbobio_print(void *aux, const char *pnp) 185 { 186 struct sbobio_attach_args *sap = aux; 187 int i; 188 189 if (pnp) 190 aprint_normal("%s at %s", 191 sbobio_device_type_name(sap->sa_locs.sa_type), pnp); 192 aprint_normal(" offset 0x%lx", (long)sap->sa_locs.sa_offset); 193 for (i = 0; i < 2; i++) { 194 if (sap->sa_locs.sa_intr[i] != SBOBIOCF_INTR_DEFAULT) 195 aprint_normal("%s%ld", i == 0 ? " intr " : ",", 196 (long)sap->sa_locs.sa_intr[i]); 197 } 198 return (UNCONF); 199 } 200 201 static const char * 202 sbobio_device_type_name(enum sbobio_device_type type) 203 { 204 205 switch (type) { 206 case SBOBIO_DEVTYPE_SMBUS: 207 return ("sbsmbus"); 208 case SBOBIO_DEVTYPE_DUART: 209 return ("sbscn"); 210 case SBOBIO_DEVTYPE_SYNCSERIAL: 211 return ("sbsync"); 212 case SBOBIO_DEVTYPE_GBUS: 213 return ("sbgbus"); 214 case SBOBIO_DEVTYPE_MAC: 215 return ("sbmac"); 216 } 217 panic("sbobio_device_type_name"); 218 return ("panic"); 219 } 220