1 /* $NetBSD: tsc.c,v 1.18 2010/10/07 19:55:02 hans Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 by Ross Harvey. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Ross Harvey. 17 * 4. The name of Ross Harvey may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY ROSS HARVEY ``AS IS'' AND ANY EXPRESS 21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP0SE 23 * ARE DISCLAIMED. IN NO EVENT SHALL ROSS HARVEY BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34 #include "opt_dec_6600.h" 35 36 #include <sys/cdefs.h> 37 38 __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.18 2010/10/07 19:55:02 hans Exp $"); 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/device.h> 43 #include <sys/malloc.h> 44 45 #include <machine/autoconf.h> 46 #include <machine/rpb.h> 47 #include <machine/sysarch.h> 48 49 #include <dev/isa/isareg.h> 50 #include <dev/isa/isavar.h> 51 #include <dev/pci/pcireg.h> 52 #include <dev/pci/pcivar.h> 53 #include <alpha/pci/tsreg.h> 54 #include <alpha/pci/tsvar.h> 55 56 #ifdef DEC_6600 57 #include <alpha/pci/pci_6600.h> 58 #endif 59 60 #define tsc() { Generate ctags(1) key. } 61 62 static int tscmatch(device_t, cfdata_t, void *); 63 static void tscattach(device_t, device_t, void *); 64 65 CFATTACH_DECL_NEW(tsc, 0, tscmatch, tscattach, NULL, NULL); 66 67 extern struct cfdriver tsc_cd; 68 69 struct tsp_config tsp_configuration[2]; 70 71 static int tscprint(void *, const char *pnp); 72 73 static int tspmatch(device_t, cfdata_t, void *); 74 static void tspattach(device_t, device_t, void *); 75 76 CFATTACH_DECL_NEW(tsp, 0, tspmatch, tspattach, NULL, NULL); 77 78 extern struct cfdriver tsp_cd; 79 80 static int tsp_bus_get_window(int, int, 81 struct alpha_bus_space_translation *); 82 83 /* There can be only one */ 84 static int tscfound; 85 86 /* Which hose is the display console connected to? */ 87 int tsp_console_hose; 88 89 static int 90 tscmatch(device_t parent, cfdata_t match, void *aux) 91 { 92 struct mainbus_attach_args *ma = aux; 93 94 return cputype == ST_DEC_6600 95 && strcmp(ma->ma_name, tsc_cd.cd_name) == 0 96 && !tscfound; 97 } 98 99 static void 100 tscattach(device_t parent, device_t self, void * aux) 101 { 102 int i; 103 int nbus; 104 uint64_t csc, aar; 105 struct tsp_attach_args tsp; 106 struct mainbus_attach_args *ma = aux; 107 108 tscfound = 1; 109 110 csc = LDQP(TS_C_CSC); 111 112 nbus = 1 + (CSC_BC(csc) >= 2); 113 printf(": 21272 Core Logic Chipset, Cchip rev %d\n" 114 "%s%d: %c Dchips, %d memory bus%s of %d bytes\n", 115 (int)MISC_REV(LDQP(TS_C_MISC)), 116 ma->ma_name, ma->ma_slot, "2448"[CSC_BC(csc)], 117 nbus, nbus > 1 ? "es" : "", 16 + 16 * ((csc & CSC_AW) != 0)); 118 printf("%s%d: arrays present: ", ma->ma_name, ma->ma_slot); 119 for(i = 0; i < 4; ++i) { 120 aar = LDQP(TS_C_AAR0 + i * TS_STEP); 121 printf("%s%dMB%s", i ? ", " : "", (8 << AAR_ASIZ(aar)) & ~0xf, 122 aar & AAR_SPLIT ? " (split)" : ""); 123 } 124 printf(", Dchip 0 rev %d\n", (int)LDQP(TS_D_DREV) & 0xf); 125 126 memset(&tsp, 0, sizeof tsp); 127 tsp.tsp_name = "tsp"; 128 config_found(self, &tsp, NULL); 129 130 if(LDQP(TS_C_CSC) & CSC_P1P) { 131 ++tsp.tsp_slot; 132 config_found(self, &tsp, tscprint); 133 } 134 } 135 136 static int 137 tscprint(void *aux, const char *p) 138 { 139 register struct tsp_attach_args *tsp = aux; 140 141 if(p) 142 aprint_normal("%s%d at %s", tsp->tsp_name, tsp->tsp_slot, p); 143 return UNCONF; 144 } 145 146 #define tsp() { Generate ctags(1) key. } 147 148 static int 149 tspmatch(device_t parent, cfdata_t match, void *aux) 150 { 151 struct tsp_attach_args *t = aux; 152 153 return cputype == ST_DEC_6600 154 && strcmp(t->tsp_name, tsp_cd.cd_name) == 0; 155 } 156 157 static void 158 tspattach(device_t parent, device_t self, void *aux) 159 { 160 struct pcibus_attach_args pba; 161 struct tsp_attach_args *t = aux; 162 struct tsp_config *pcp; 163 164 printf("\n"); 165 pcp = tsp_init(1, t->tsp_slot); 166 167 tsp_dma_init(pcp); 168 169 /* 170 * Do PCI memory initialization that needs to be deferred until 171 * malloc is safe. On the Tsunami, we need to do this after 172 * DMA is initialized, as well. 173 */ 174 tsp_bus_mem_init2(&pcp->pc_memt, pcp); 175 176 pci_6600_pickintr(pcp); 177 178 pba.pba_iot = &pcp->pc_iot; 179 pba.pba_memt = &pcp->pc_memt; 180 pba.pba_dmat = 181 alphabus_dma_get_tag(&pcp->pc_dmat_direct, ALPHA_BUS_PCI); 182 pba.pba_dmat64 = NULL; 183 pba.pba_pc = &pcp->pc_pc; 184 pba.pba_bus = 0; 185 pba.pba_bridgetag = NULL; 186 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | 187 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 188 config_found_ia(self, "pcibus", &pba, pcibusprint); 189 } 190 191 struct tsp_config * 192 tsp_init(int mallocsafe, int n) 193 /* n: Pchip number */ 194 { 195 struct tsp_config *pcp; 196 197 KASSERT((n | 1) == 1); 198 pcp = &tsp_configuration[n]; 199 pcp->pc_pslot = n; 200 pcp->pc_iobase = TS_Pn(n, 0); 201 pcp->pc_csr = S_PAGE(TS_Pn(n, P_CSRBASE)); 202 if (!pcp->pc_initted) { 203 tsp_bus_io_init(&pcp->pc_iot, pcp); 204 tsp_bus_mem_init(&pcp->pc_memt, pcp); 205 206 alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_IO] = 1; 207 alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_MEM] = 1; 208 209 alpha_bus_get_window = tsp_bus_get_window; 210 } 211 pcp->pc_mallocsafe = mallocsafe; 212 tsp_pci_init(&pcp->pc_pc, pcp); 213 pcp->pc_initted = 1; 214 return pcp; 215 } 216 217 static int 218 tsp_bus_get_window(int type, int window, 219 struct alpha_bus_space_translation *abst) 220 { 221 struct tsp_config *tsp = &tsp_configuration[tsp_console_hose]; 222 bus_space_tag_t st; 223 int error; 224 225 switch (type) { 226 case ALPHA_BUS_TYPE_PCI_IO: 227 st = &tsp->pc_iot; 228 break; 229 230 case ALPHA_BUS_TYPE_PCI_MEM: 231 st = &tsp->pc_memt; 232 break; 233 234 default: 235 panic("tsp_bus_get_window"); 236 } 237 238 error = alpha_bus_space_get_window(st, window, abst); 239 if (error) 240 return (error); 241 242 abst->abst_sys_start = TS_PHYSADDR(abst->abst_sys_start); 243 abst->abst_sys_end = TS_PHYSADDR(abst->abst_sys_end); 244 245 return (0); 246 } 247 248 void 249 tsc_print_dir(unsigned int indent, unsigned long dir) 250 { 251 char buf[60]; 252 253 snprintb(buf, 60, 254 "\177\20" 255 "b\77Internal Cchip asynchronous error\0" 256 "b\76Pchip 0 error\0" 257 "b\75Pchip 1 error\0" 258 "b\74Pchip 2 error\0" 259 "b\73Pchip 3 error\0", 260 dir); 261 IPRINTF(indent, "DIR = %s\n", buf); 262 } 263 264 void 265 tsc_print_misc(unsigned int indent, unsigned long misc) 266 { 267 unsigned long tmp = MISC_NXM_SRC(misc); 268 269 if (!MISC_NXM(misc)) 270 return; 271 272 IPRINTF(indent, "NXM address detected\n"); 273 IPRINTF(indent, "NXM source = %s %lu\n", 274 tmp <= 3 ? "CPU" : "Pchip", tmp <= 3 ? tmp : tmp - 4); 275 } 276