1 /* $NetBSD: imc.c,v 1.7 2002/10/02 15:52:32 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Rafal K. Boni 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/device.h> 32 #include <sys/systm.h> 33 34 #include <machine/cpu.h> 35 #include <machine/locore.h> 36 #include <machine/autoconf.h> 37 #include <machine/bus.h> 38 #include <machine/machtype.h> 39 40 #include <sgimips/dev/imcreg.h> 41 42 #include "locators.h" 43 44 struct imc_softc { 45 struct device sc_dev; 46 47 int eisa_present : 1; 48 }; 49 50 static int imc_match(struct device *, struct cfdata *, void *); 51 static void imc_attach(struct device *, struct device *, void *); 52 static int imc_print(void *, const char *); 53 54 CFATTACH_DECL(imc, sizeof(struct imc_softc), 55 imc_match, imc_attach, NULL, NULL); 56 57 struct imc_attach_args { 58 const char* iaa_name; 59 60 bus_space_tag_t iaa_st; 61 bus_space_handle_t iaa_sh; 62 63 /* ? */ 64 long iaa_offset; 65 int iaa_intr; 66 #if 0 67 int iaa_stride; 68 #endif 69 }; 70 71 static int 72 imc_match(parent, match, aux) 73 struct device *parent; 74 struct cfdata *match; 75 void *aux; 76 { 77 78 /* 79 * The IMC is an INDY/INDIGO2 thing. 80 */ 81 if (mach_type != MACH_SGI_IP22) 82 return (0); 83 84 /* Make sure it's actually there and readable */ 85 if (badaddr((void*)MIPS_PHYS_TO_KSEG1(IMC_SYSID), sizeof(u_int32_t))) 86 return (0); 87 88 return (1); 89 } 90 91 static void 92 imc_attach(parent, self, aux) 93 struct device *parent; 94 struct device *self; 95 void *aux; 96 { 97 u_int32_t reg; 98 struct imc_attach_args iaa; 99 struct imc_softc *isc = (void *) self; 100 u_int32_t sysid = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_SYSID); 101 102 /* EISA present bit is on even on Indys, so don't trust it! */ 103 if (mach_subtype == MACH_SGI_IP22_FULLHOUSE) 104 isc->eisa_present = (sysid & IMC_SYSID_HAVEISA); 105 else 106 isc->eisa_present = 0; 107 108 printf("\nimc0: Revision %d", (sysid & IMC_SYSID_REVMASK)); 109 110 if (isc->eisa_present) 111 printf(", EISA bus present"); 112 113 printf("\n"); 114 115 /* Clear CPU/GIO error status registers to clear any leftover bits. */ 116 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPU_ERRSTAT) = 0; 117 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_GIO_ERRSTAT) = 0; 118 119 /* 120 * Enable parity reporting on GIO/main memory transactions. 121 * Disable parity checking on CPU bus transactions (as turning 122 * it on seems to cause spurious bus errors), but enable parity 123 * checking on CPU reads from main memory (note that this bit 124 * has the opposite sense... Turning it on turns the checks off!). 125 * Finally, turn on interrupt writes to the CPU from the MC. 126 */ 127 reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL0); 128 reg &= ~IMC_CPUCTRL0_NCHKMEMPAR; 129 reg |= (IMC_CPUCTRL0_GPR | IMC_CPUCTRL0_MPR | IMC_CPUCTRL0_INTENA); 130 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL0) = reg; 131 132 /* Setup the MC write buffer depth */ 133 reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL1); 134 reg = (reg & ~IMC_CPUCTRL1_MCHWMSK) | 13; 135 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL1) = reg; 136 137 /* 138 * Set GIO64 arbitrator configuration register: 139 * 140 * Preserve PROM-set graphics-related bits, as they seem to depend 141 * on the graphics variant present and I'm not sure how to figure 142 * that out or 100% sure what the correct settings are for each. 143 */ 144 reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_GIO64ARB); 145 reg &= (IMC_GIO64ARB_GRX64 | IMC_GIO64ARB_GRXRT | IMC_GIO64ARB_GRXMST); 146 147 /* GIO64 invariant for all IP22 platforms: one GIO bus, HPC1 @ 64 */ 148 reg |= IMC_GIO64ARB_ONEGIO | IMC_GIO64ARB_HPC64; 149 150 /* Rest of settings are machine/board dependant */ 151 switch (mach_subtype) { 152 case MACH_SGI_IP22_GUINESS: 153 /* EISA can bus-master, is 64-bit */ 154 reg |= (IMC_GIO64ARB_EISAMST | IMC_GIO64ARB_EISA64); 155 break; 156 157 case MACH_SGI_IP22_FULLHOUSE: 158 /* 159 * All Fullhouse boards have a 64-bit HPC2 and pipelined 160 * EXP0 slot. 161 */ 162 reg |= (IMC_GIO64ARB_HPCEXP64 | IMC_GIO64ARB_EXP0PIPE); 163 164 if (mach_boardrev < 2) { 165 /* EXP0 realtime, EXP1 can master */ 166 reg |= (IMC_GIO64ARB_EXP0RT | IMC_GIO64ARB_EXP1MST); 167 } else { 168 /* EXP1 pipelined as well, EISA masters */ 169 reg |= (IMC_GIO64ARB_EXP1PIPE | IMC_GIO64ARB_EISAMST); 170 } 171 break; 172 } 173 174 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_GIO64ARB) = reg; 175 176 if (isc->eisa_present) { 177 #if notyet 178 memset(&iaa, 0, sizeof(iaa)); 179 180 iaa.iaa_name = "eisa"; 181 (void)config_found(self, (void*)&iaa, imc_print); 182 #endif 183 } 184 185 memset(&iaa, 0, sizeof(iaa)); 186 187 iaa.iaa_name = "gio"; 188 (void)config_found(self, (void*)&iaa, imc_print); 189 } 190 191 192 static int 193 imc_print(aux, name) 194 void *aux; 195 const char *name; 196 { 197 struct imc_attach_args* iaa = aux; 198 199 if (name) 200 printf("%s at %s", iaa->iaa_name, name); 201 202 return UNCONF; 203 } 204 205