1 1.81 thorpej /* $NetBSD: cia.c,v 1.81 2023/12/04 00:32:10 thorpej Exp $ */ 2 1.42 thorpej 3 1.42 thorpej /*- 4 1.53 thorpej * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. 5 1.42 thorpej * All rights reserved. 6 1.42 thorpej * 7 1.42 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.42 thorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.42 thorpej * NASA Ames Research Center. 10 1.42 thorpej * 11 1.42 thorpej * Redistribution and use in source and binary forms, with or without 12 1.42 thorpej * modification, are permitted provided that the following conditions 13 1.42 thorpej * are met: 14 1.42 thorpej * 1. Redistributions of source code must retain the above copyright 15 1.42 thorpej * notice, this list of conditions and the following disclaimer. 16 1.42 thorpej * 2. Redistributions in binary form must reproduce the above copyright 17 1.42 thorpej * notice, this list of conditions and the following disclaimer in the 18 1.42 thorpej * documentation and/or other materials provided with the distribution. 19 1.42 thorpej * 20 1.42 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.42 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.42 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.42 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.42 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.42 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.42 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.42 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.42 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.42 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.42 thorpej * POSSIBILITY OF SUCH DAMAGE. 31 1.42 thorpej */ 32 1.1 cgd 33 1.1 cgd /* 34 1.4 cgd * Copyright (c) 1995, 1996 Carnegie-Mellon University. 35 1.1 cgd * All rights reserved. 36 1.1 cgd * 37 1.1 cgd * Author: Chris G. Demetriou 38 1.73 matt * 39 1.1 cgd * Permission to use, copy, modify and distribute this software and 40 1.1 cgd * its documentation is hereby granted, provided that both the copyright 41 1.1 cgd * notice and this permission notice appear in all copies of the 42 1.1 cgd * software, derivative works or modified versions, and any portions 43 1.1 cgd * thereof, and that both notices appear in supporting documentation. 44 1.73 matt * 45 1.73 matt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 1.73 matt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 1.1 cgd * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 1.73 matt * 49 1.1 cgd * Carnegie Mellon requests users of this software to return to 50 1.1 cgd * 51 1.1 cgd * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 52 1.1 cgd * School of Computer Science 53 1.1 cgd * Carnegie Mellon University 54 1.1 cgd * Pittsburgh PA 15213-3890 55 1.1 cgd * 56 1.1 cgd * any improvements or extensions that they make and grant Carnegie the 57 1.1 cgd * rights to redistribute these changes. 58 1.1 cgd */ 59 1.18 cgd 60 1.39 thorpej #include "opt_dec_550.h" 61 1.25 thorpej 62 1.19 cgd #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 63 1.19 cgd 64 1.81 thorpej __KERNEL_RCSID(0, "$NetBSD: cia.c,v 1.81 2023/12/04 00:32:10 thorpej Exp $"); 65 1.1 cgd 66 1.1 cgd #include <sys/param.h> 67 1.1 cgd #include <sys/systm.h> 68 1.1 cgd #include <sys/kernel.h> 69 1.1 cgd #include <sys/device.h> 70 1.56 mrg 71 1.1 cgd #include <machine/autoconf.h> 72 1.1 cgd #include <machine/rpb.h> 73 1.53 thorpej #include <machine/sysarch.h> 74 1.57 ross #include <machine/alpha.h> 75 1.1 cgd 76 1.1 cgd #include <dev/isa/isareg.h> 77 1.1 cgd #include <dev/isa/isavar.h> 78 1.1 cgd 79 1.1 cgd #include <dev/pci/pcireg.h> 80 1.1 cgd #include <dev/pci/pcivar.h> 81 1.1 cgd #include <alpha/pci/ciareg.h> 82 1.1 cgd #include <alpha/pci/ciavar.h> 83 1.45 ross 84 1.76 thorpej static int ciamatch(device_t, cfdata_t, void *); 85 1.76 thorpej static void ciaattach(device_t, device_t, void *); 86 1.1 cgd 87 1.72 matt CFATTACH_DECL_NEW(cia, sizeof(struct cia_softc), 88 1.60 thorpej ciamatch, ciaattach, NULL, NULL); 89 1.5 cgd 90 1.29 thorpej extern struct cfdriver cia_cd; 91 1.1 cgd 92 1.76 thorpej static int cia_bus_get_window(int, int, 93 1.76 thorpej struct alpha_bus_space_translation *); 94 1.53 thorpej 95 1.1 cgd /* There can be only one. */ 96 1.76 thorpej static int ciafound; 97 1.1 cgd struct cia_config cia_configuration; 98 1.1 cgd 99 1.37 thorpej /* 100 1.37 thorpej * This determines if we attempt to use BWX for PCI bus and config space 101 1.37 thorpej * access. Some systems, notably with Pyxis, don't fare so well unless 102 1.37 thorpej * BWX is used. 103 1.46 thorpej * 104 1.46 thorpej * EXCEPT! Some devices have a really hard time if BWX is used (WHY?!). 105 1.46 thorpej * So, we decouple the uses for PCI config space and PCI bus space. 106 1.50 thorpej * 107 1.50 thorpej * FURTHERMORE! The Pyxis, most notably earlier revs, really don't 108 1.50 thorpej * do so well if you don't use BWX for bus access. So we default to 109 1.50 thorpej * forcing BWX on those chips. 110 1.50 thorpej * 111 1.50 thorpej * Geez. 112 1.37 thorpej */ 113 1.46 thorpej 114 1.46 thorpej #ifndef CIA_PCI_USE_BWX 115 1.46 thorpej #define CIA_PCI_USE_BWX 1 116 1.46 thorpej #endif 117 1.46 thorpej 118 1.46 thorpej #ifndef CIA_BUS_USE_BWX 119 1.46 thorpej #define CIA_BUS_USE_BWX 0 120 1.37 thorpej #endif 121 1.37 thorpej 122 1.50 thorpej #ifndef CIA_PYXIS_FORCE_BWX 123 1.52 thorpej #define CIA_PYXIS_FORCE_BWX 0 124 1.50 thorpej #endif 125 1.50 thorpej 126 1.46 thorpej int cia_pci_use_bwx = CIA_PCI_USE_BWX; 127 1.46 thorpej int cia_bus_use_bwx = CIA_BUS_USE_BWX; 128 1.50 thorpej int cia_pyxis_force_bwx = CIA_PYXIS_FORCE_BWX; 129 1.37 thorpej 130 1.76 thorpej static int 131 1.72 matt ciamatch(device_t parent, cfdata_t match, void *aux) 132 1.1 cgd { 133 1.35 thorpej struct mainbus_attach_args *ma = aux; 134 1.1 cgd 135 1.1 cgd /* Make sure that we're looking for a CIA. */ 136 1.35 thorpej if (strcmp(ma->ma_name, cia_cd.cd_name) != 0) 137 1.1 cgd return (0); 138 1.1 cgd 139 1.1 cgd if (ciafound) 140 1.1 cgd return (0); 141 1.1 cgd 142 1.1 cgd return (1); 143 1.1 cgd } 144 1.1 cgd 145 1.1 cgd /* 146 1.1 cgd * Set up the chipset's function pointers. 147 1.1 cgd */ 148 1.1 cgd void 149 1.81 thorpej cia_init(struct cia_config *ccp) 150 1.1 cgd { 151 1.50 thorpej int pci_use_bwx = cia_pci_use_bwx; 152 1.50 thorpej int bus_use_bwx = cia_bus_use_bwx; 153 1.1 cgd 154 1.6 cgd ccp->cc_hae_mem = REGVAL(CIA_CSR_HAE_MEM); 155 1.6 cgd ccp->cc_hae_io = REGVAL(CIA_CSR_HAE_IO); 156 1.36 thorpej ccp->cc_rev = REGVAL(CIA_CSR_REV) & REV_MASK; 157 1.36 thorpej 158 1.36 thorpej /* 159 1.36 thorpej * Determine if we have a Pyxis. Only two systypes can 160 1.36 thorpej * have this: the EB164 systype (AlphaPC164LX and AlphaPC164SX) 161 1.36 thorpej * and the DEC_550 systype (Miata). 162 1.36 thorpej */ 163 1.47 cgd if ((cputype == ST_EB164 && 164 1.36 thorpej (hwrpb->rpb_variation & SV_ST_MASK) >= SV_ST_ALPHAPC164LX_400) || 165 1.50 thorpej cputype == ST_DEC_550) { 166 1.36 thorpej ccp->cc_flags |= CCF_ISPYXIS; 167 1.50 thorpej if (cia_pyxis_force_bwx) 168 1.50 thorpej pci_use_bwx = bus_use_bwx = 1; 169 1.50 thorpej } 170 1.27 thorpej 171 1.27 thorpej /* 172 1.40 thorpej * ALCOR/ALCOR2 Revisions >= 2 and Pyxis have the CNFG register. 173 1.27 thorpej */ 174 1.40 thorpej if (ccp->cc_rev >= 2 || (ccp->cc_flags & CCF_ISPYXIS) != 0) 175 1.27 thorpej ccp->cc_cnfg = REGVAL(CIA_CSR_CNFG); 176 1.27 thorpej else 177 1.27 thorpej ccp->cc_cnfg = 0; 178 1.12 cgd 179 1.37 thorpej /* 180 1.37 thorpej * Use BWX iff: 181 1.37 thorpej * 182 1.80 andvar * - It hasn't been disabled by the user, 183 1.37 thorpej * - it's enabled in CNFG, 184 1.37 thorpej * - we're implementation version ev5, 185 1.57 ross * - BWX is enabled in the CPU's capabilities mask 186 1.37 thorpej */ 187 1.50 thorpej if ((pci_use_bwx || bus_use_bwx) && 188 1.37 thorpej (ccp->cc_cnfg & CNFG_BWEN) != 0 && 189 1.55 thorpej (cpu_amask & ALPHA_AMASK_BWX) != 0) { 190 1.73 matt uint32_t ctrl; 191 1.38 thorpej 192 1.50 thorpej if (pci_use_bwx) 193 1.46 thorpej ccp->cc_flags |= CCF_PCI_USE_BWX; 194 1.50 thorpej if (bus_use_bwx) 195 1.46 thorpej ccp->cc_flags |= CCF_BUS_USE_BWX; 196 1.38 thorpej 197 1.38 thorpej /* 198 1.38 thorpej * For whatever reason, the firmware seems to enable PCI 199 1.38 thorpej * loopback mode if it also enables BWX. Make sure it's 200 1.38 thorpej * enabled if we have an old, buggy firmware rev. 201 1.38 thorpej */ 202 1.38 thorpej alpha_mb(); 203 1.38 thorpej ctrl = REGVAL(CIA_CSR_CTRL); 204 1.38 thorpej if ((ctrl & CTRL_PCI_LOOP_EN) == 0) { 205 1.38 thorpej REGVAL(CIA_CSR_CTRL) = ctrl | CTRL_PCI_LOOP_EN; 206 1.38 thorpej alpha_mb(); 207 1.38 thorpej } 208 1.38 thorpej } 209 1.37 thorpej 210 1.14 cgd if (!ccp->cc_initted) { 211 1.14 cgd /* don't do these twice since they set up extents */ 212 1.46 thorpej if (ccp->cc_flags & CCF_BUS_USE_BWX) { 213 1.37 thorpej cia_bwx_bus_io_init(&ccp->cc_iot, ccp); 214 1.37 thorpej cia_bwx_bus_mem_init(&ccp->cc_memt, ccp); 215 1.53 thorpej 216 1.53 thorpej /* 217 1.53 thorpej * We have one window for both PCI I/O and MEM 218 1.53 thorpej * in BWX mode. 219 1.53 thorpej */ 220 1.53 thorpej alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_IO] = 1; 221 1.53 thorpej alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_MEM] = 1; 222 1.37 thorpej } else { 223 1.37 thorpej cia_swiz_bus_io_init(&ccp->cc_iot, ccp); 224 1.37 thorpej cia_swiz_bus_mem_init(&ccp->cc_memt, ccp); 225 1.53 thorpej 226 1.53 thorpej /* 227 1.53 thorpej * We have two I/O windows and 4 MEM windows in 228 1.53 thorpej * SWIZ mode. 229 1.53 thorpej */ 230 1.53 thorpej alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_IO] = 2; 231 1.53 thorpej alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_MEM] = 4; 232 1.37 thorpej } 233 1.53 thorpej alpha_bus_get_window = cia_bus_get_window; 234 1.14 cgd } 235 1.14 cgd 236 1.14 cgd cia_pci_init(&ccp->cc_pc, ccp); 237 1.53 thorpej alpha_pci_chipset = &ccp->cc_pc; 238 1.14 cgd 239 1.14 cgd ccp->cc_initted = 1; 240 1.1 cgd } 241 1.1 cgd 242 1.76 thorpej static void 243 1.72 matt ciaattach(device_t parent, device_t self, void *aux) 244 1.1 cgd { 245 1.72 matt struct cia_softc *sc = device_private(self); 246 1.1 cgd struct cia_config *ccp; 247 1.5 cgd struct pcibus_attach_args pba; 248 1.28 thorpej char bits[64]; 249 1.43 thorpej const char *name; 250 1.1 cgd 251 1.1 cgd /* note that we've attached the chipset; can't have 2 CIAs. */ 252 1.1 cgd ciafound = 1; 253 1.72 matt sc->sc_dev = self; 254 1.1 cgd 255 1.1 cgd /* 256 1.1 cgd * set up the chipset's info; done once at console init time 257 1.21 thorpej * (maybe), but we must do it here as well to take care of things 258 1.21 thorpej * that need to use memory allocation. 259 1.1 cgd */ 260 1.1 cgd ccp = sc->sc_ccp = &cia_configuration; 261 1.81 thorpej cia_init(ccp); 262 1.1 cgd 263 1.43 thorpej if (ccp->cc_flags & CCF_ISPYXIS) { 264 1.43 thorpej name = "Pyxis"; 265 1.43 thorpej } else { 266 1.43 thorpej name = "ALCOR/ALCOR2"; 267 1.43 thorpej } 268 1.43 thorpej 269 1.72 matt aprint_normal(": DECchip 2117x Core Logic Chipset (%s), pass %d\n", 270 1.74 martin name, ccp->cc_rev + 1); 271 1.66 christos if (ccp->cc_cnfg) { 272 1.66 christos snprintb(bits, sizeof(bits), CIA_CSR_CNFG_BITS, ccp->cc_cnfg); 273 1.72 matt aprint_normal_dev(self, "extended capabilities: %s\n", bits); 274 1.66 christos } 275 1.46 thorpej 276 1.46 thorpej switch (ccp->cc_flags & (CCF_PCI_USE_BWX|CCF_BUS_USE_BWX)) { 277 1.46 thorpej case CCF_PCI_USE_BWX|CCF_BUS_USE_BWX: 278 1.46 thorpej name = "PCI config and bus"; 279 1.46 thorpej break; 280 1.46 thorpej case CCF_PCI_USE_BWX: 281 1.46 thorpej name = "PCI config"; 282 1.46 thorpej break; 283 1.46 thorpej case CCF_BUS_USE_BWX: 284 1.46 thorpej name = "bus"; 285 1.46 thorpej break; 286 1.46 thorpej default: 287 1.46 thorpej name = NULL; 288 1.46 thorpej break; 289 1.46 thorpej } 290 1.46 thorpej if (name != NULL) 291 1.72 matt aprint_normal_dev(self, "using BWX for %s access\n", name); 292 1.41 thorpej 293 1.42 thorpej #ifdef DEC_550 294 1.47 cgd if (cputype == ST_DEC_550 && 295 1.42 thorpej (hwrpb->rpb_variation & SV_ST_MASK) < SV_ST_MIATA_1_5) { 296 1.41 thorpej /* 297 1.42 thorpej * Miata 1 systems have a bug: DMA cannot cross 298 1.41 thorpej * an 8k boundary! Make sure PCI read prefetching 299 1.41 thorpej * is disabled on these chips. Note that secondary 300 1.41 thorpej * PCI busses don't have this problem, because of 301 1.41 thorpej * the way PPBs handle PCI read requests. 302 1.41 thorpej * 303 1.42 thorpej * In the 21174 Technical Reference Manual, this is 304 1.42 thorpej * actually documented as "Pyxis Pass 1", but apparently 305 1.42 thorpej * there are chips that report themselves as "Pass 1" 306 1.42 thorpej * which do not have the bug! Miatas with the Cypress 307 1.42 thorpej * PCI-ISA bridge (i.e. Miata 1.5 and Miata 2) do not 308 1.42 thorpej * have the bug, so we use this check. 309 1.42 thorpej * 310 1.51 thorpej * NOTE: This bug is actually worked around in cia_dma.c, 311 1.51 thorpej * when direct-mapped DMA maps are created. 312 1.51 thorpej * 313 1.51 thorpej * XXX WE NEED TO THINK ABOUT HOW TO HANDLE THIS FOR 314 1.51 thorpej * XXX SGMAP DMA MAPPINGS! 315 1.41 thorpej */ 316 1.73 matt uint32_t ctrl; 317 1.41 thorpej 318 1.41 thorpej /* XXX no bets... */ 319 1.72 matt aprint_error_dev(self, 320 1.72 matt "WARNING: Pyxis pass 1 DMA bug; no bets...\n"); 321 1.41 thorpej 322 1.49 thorpej ccp->cc_flags |= CCF_PYXISBUG; 323 1.49 thorpej 324 1.41 thorpej alpha_mb(); 325 1.41 thorpej ctrl = REGVAL(CIA_CSR_CTRL); 326 1.41 thorpej ctrl &= ~(CTRL_RD_TYPE|CTRL_RL_TYPE|CTRL_RM_TYPE); 327 1.41 thorpej REGVAL(CIA_CSR_CTRL) = ctrl; 328 1.41 thorpej alpha_mb(); 329 1.41 thorpej } 330 1.42 thorpej #endif /* DEC_550 */ 331 1.43 thorpej 332 1.43 thorpej cia_dma_init(ccp); 333 1.1 cgd 334 1.77 thorpej alpha_pci_intr_init(ccp, &ccp->cc_iot, &ccp->cc_memt, &ccp->cc_pc); 335 1.1 cgd 336 1.23 thorpej pba.pba_iot = &ccp->cc_iot; 337 1.23 thorpej pba.pba_memt = &ccp->cc_memt; 338 1.30 thorpej pba.pba_dmat = 339 1.30 thorpej alphabus_dma_get_tag(&ccp->cc_dmat_direct, ALPHA_BUS_PCI); 340 1.62 fvdl pba.pba_dmat64 = NULL; 341 1.5 cgd pba.pba_pc = &ccp->cc_pc; 342 1.5 cgd pba.pba_bus = 0; 343 1.58 thorpej pba.pba_bridgetag = NULL; 344 1.71 dyoung pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; 345 1.49 thorpej if ((ccp->cc_flags & CCF_PYXISBUG) == 0) 346 1.49 thorpej pba.pba_flags |= PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | 347 1.49 thorpej PCI_FLAGS_MWI_OKAY; 348 1.79 thorpej config_found(self, &pba, pcibusprint, CFARGS_NONE); 349 1.53 thorpej } 350 1.53 thorpej 351 1.76 thorpej static int 352 1.76 thorpej cia_bus_get_window(int type, int window, 353 1.76 thorpej struct alpha_bus_space_translation *abst) 354 1.53 thorpej { 355 1.53 thorpej struct cia_config *ccp = &cia_configuration; 356 1.53 thorpej bus_space_tag_t st; 357 1.53 thorpej 358 1.53 thorpej switch (type) { 359 1.53 thorpej case ALPHA_BUS_TYPE_PCI_IO: 360 1.53 thorpej st = &ccp->cc_iot; 361 1.53 thorpej break; 362 1.53 thorpej 363 1.53 thorpej case ALPHA_BUS_TYPE_PCI_MEM: 364 1.53 thorpej st = &ccp->cc_memt; 365 1.53 thorpej break; 366 1.53 thorpej 367 1.53 thorpej default: 368 1.53 thorpej panic("cia_bus_get_window"); 369 1.53 thorpej } 370 1.53 thorpej 371 1.53 thorpej return (alpha_bus_space_get_window(st, window, abst)); 372 1.54 thorpej } 373 1.54 thorpej 374 1.54 thorpej void 375 1.69 dsl cia_pyxis_intr_enable(int irq, int onoff) 376 1.54 thorpej { 377 1.73 matt uint64_t imask; 378 1.54 thorpej int s; 379 1.54 thorpej 380 1.54 thorpej #if 0 381 1.54 thorpej printf("cia_pyxis_intr_enable: %s %d\n", 382 1.54 thorpej onoff ? "enabling" : "disabling", irq); 383 1.54 thorpej #endif 384 1.54 thorpej 385 1.54 thorpej s = splhigh(); 386 1.54 thorpej alpha_mb(); 387 1.54 thorpej imask = REGVAL64(PYXIS_INT_MASK); 388 1.54 thorpej if (onoff) 389 1.54 thorpej imask |= (1UL << irq); 390 1.54 thorpej else 391 1.54 thorpej imask &= ~(1UL << irq); 392 1.54 thorpej REGVAL64(PYXIS_INT_MASK) = imask; 393 1.54 thorpej alpha_mb(); 394 1.54 thorpej splx(s); 395 1.1 cgd } 396