1 1.6 thorpej /* $NetBSD: oioc.c,v 1.6 2021/08/07 16:19:04 thorpej Exp $ */ 2 1.1 rumble 3 1.1 rumble /* 4 1.1 rumble * Copyright (c) 2009 Stephen M. Rumble 5 1.1 rumble * All rights reserved. 6 1.1 rumble * 7 1.1 rumble * Redistribution and use in source and binary forms, with or without 8 1.1 rumble * modification, are permitted provided that the following conditions 9 1.1 rumble * are met: 10 1.1 rumble * 1. Redistributions of source code must retain the above copyright 11 1.1 rumble * notice, this list of conditions and the following disclaimer. 12 1.1 rumble * 2. The name of the author may not be used to endorse or promote products 13 1.1 rumble * derived from this software without specific prior written permission. 14 1.1 rumble * 15 1.1 rumble * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.1 rumble * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 1.1 rumble * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 1.1 rumble * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 1.1 rumble * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 1.1 rumble * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 1.1 rumble * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 1.1 rumble * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 1.1 rumble * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 1.1 rumble * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 1.1 rumble */ 26 1.1 rumble 27 1.1 rumble /* 28 1.1 rumble * IOC1/IOC2 chips on IP4 and IP6/IP10 machines. This interfaces the SCSI 29 1.1 rumble * and Ethernet controllers, performs DMA for the former, and does address 30 1.1 rumble * space translation for the latter (maps the lance memory space to physical 31 1.1 rumble * pages). 32 1.1 rumble * 33 1.1 rumble * 'I/O Controller' is a sufficiently generic name that SGI created another 34 1.1 rumble * one for IP24, which basically stuffed a bunch of miscellany on an ASIC. 35 1.1 rumble * So, we'll call ourselves 'Old IOC' and hope that there wasn't an even older 36 1.1 rumble * one. 37 1.1 rumble */ 38 1.1 rumble 39 1.1 rumble #include <sys/cdefs.h> 40 1.6 thorpej __KERNEL_RCSID(0, "$NetBSD: oioc.c,v 1.6 2021/08/07 16:19:04 thorpej Exp $"); 41 1.1 rumble 42 1.1 rumble #include <sys/param.h> 43 1.1 rumble #include <sys/device.h> 44 1.1 rumble 45 1.1 rumble #include <machine/cpu.h> 46 1.1 rumble #include <machine/locore.h> 47 1.1 rumble #include <machine/autoconf.h> 48 1.2 dyoung #include <sys/bus.h> 49 1.1 rumble #include <machine/machtype.h> 50 1.1 rumble #include <machine/sysconf.h> 51 1.1 rumble 52 1.1 rumble #include <sgimips/ioc/oiocreg.h> 53 1.1 rumble #include <sgimips/ioc/oiocvar.h> 54 1.1 rumble 55 1.1 rumble #include "locators.h" 56 1.1 rumble 57 1.1 rumble struct oioc_softc { 58 1.1 rumble int sc_burst_dma; 59 1.1 rumble 60 1.1 rumble bus_space_tag_t sc_iot; 61 1.1 rumble bus_space_handle_t sc_ioh; 62 1.1 rumble }; 63 1.1 rumble 64 1.3 chs static int oioc_match(device_t, cfdata_t, void *); 65 1.3 chs static void oioc_attach(device_t, device_t, void *); 66 1.1 rumble static int oioc_print(void *, const char *); 67 1.1 rumble 68 1.3 chs CFATTACH_DECL_NEW(oioc, sizeof(struct oioc_softc), 69 1.1 rumble oioc_match, oioc_attach, NULL, NULL); 70 1.1 rumble 71 1.1 rumble struct oioc_device { 72 1.1 rumble const char *od_name; 73 1.1 rumble int od_irq; 74 1.1 rumble } oioc_devices[] = { 75 1.1 rumble { "oiocsc", 4 }, 76 1.1 rumble { "le", 5 }, 77 1.1 rumble { NULL, 0 } 78 1.1 rumble }; 79 1.1 rumble 80 1.1 rumble static int 81 1.3 chs oioc_match(device_t parent, cfdata_t match, void *aux) 82 1.1 rumble { 83 1.1 rumble 84 1.1 rumble switch(mach_type) { 85 1.1 rumble case MACH_SGI_IP4: 86 1.1 rumble case MACH_SGI_IP6 | MACH_SGI_IP10: 87 1.1 rumble return (1); 88 1.1 rumble } 89 1.1 rumble 90 1.1 rumble return (0); 91 1.1 rumble } 92 1.1 rumble 93 1.1 rumble static void 94 1.3 chs oioc_attach(device_t parent, device_t self, void *aux) 95 1.1 rumble { 96 1.3 chs struct oioc_softc *sc = device_private(self); 97 1.1 rumble struct mainbus_attach_args *ma = aux; 98 1.1 rumble uint32_t reg1, reg2; 99 1.1 rumble int oiocrev, i; 100 1.1 rumble 101 1.4 macallan sc->sc_iot = normal_memt; 102 1.4 macallan if (bus_space_map(sc->sc_iot, ma->ma_addr, OIOC_SCSI_REGS_SIZE, 103 1.1 rumble BUS_SPACE_MAP_LINEAR, &sc->sc_ioh)) 104 1.1 rumble panic("oioc_attach: could not allocate memory\n"); 105 1.1 rumble 106 1.1 rumble if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ma->ma_addr + 107 1.1 rumble OIOC2_CONFIG), 4)) 108 1.1 rumble oiocrev = 1; 109 1.1 rumble else 110 1.1 rumble oiocrev = 2; 111 1.1 rumble 112 1.1 rumble printf("\noioc0: Old SGI IOC%d\n", oiocrev); 113 1.1 rumble 114 1.1 rumble if (oiocrev == 2) { 115 1.1 rumble char buf[64]; 116 1.1 rumble 117 1.1 rumble /* Try to enable burst mode. If we can't, we can't... */ 118 1.1 rumble reg1 = 12 << OIOC2_CONFIG_HIWAT_SHFT; 119 1.1 rumble reg1 |= OIOC2_CONFIG_BURST_MASK; 120 1.1 rumble bus_space_write_4(sc->sc_iot, sc->sc_ioh, OIOC2_CONFIG, reg1); 121 1.1 rumble DELAY(1000); 122 1.1 rumble reg2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, OIOC2_CONFIG); 123 1.1 rumble if ((reg2 & (reg1 | OIOC2_CONFIG_NOSYNC_MASK)) == reg1) 124 1.1 rumble sc->sc_burst_dma = 1; 125 1.1 rumble 126 1.1 rumble snprintb(buf, sizeof(buf), 127 1.1 rumble "\177\020" 128 1.1 rumble "f\0\4HIWAT\0" 129 1.1 rumble "f\4\2ID\0" 130 1.1 rumble "b\6NOSYNC\0" 131 1.1 rumble "b\7BURST\0" 132 1.1 rumble "f\x8\7COUNT\0" 133 1.1 rumble "f\x10\6SCP\0" 134 1.1 rumble "f\x1c\4IOP\0\0", 135 1.1 rumble (u_quad_t)reg2 & 0xffffffff); 136 1.1 rumble printf("oioc0: %s\n", buf); 137 1.1 rumble } 138 1.1 rumble 139 1.1 rumble printf("oioc0: Burst DMA %ssupported\n", 140 1.1 rumble (sc->sc_burst_dma) ? "" : "not "); 141 1.1 rumble 142 1.1 rumble for (i = 0; oioc_devices[i].od_name != NULL; i++) { 143 1.1 rumble struct oioc_attach_args oa; 144 1.1 rumble 145 1.1 rumble oa.oa_name = oioc_devices[i].od_name; 146 1.1 rumble oa.oa_irq = oioc_devices[i].od_irq; 147 1.1 rumble oa.oa_burst_dma = sc->sc_burst_dma; 148 1.4 macallan oa.oa_st = normal_memt; 149 1.1 rumble oa.oa_sh = sc->sc_ioh; 150 1.1 rumble oa.oa_dmat = &sgimips_default_bus_dma_tag; 151 1.6 thorpej config_found(self, &oa, oioc_print, CFARGS_NONE); 152 1.1 rumble } 153 1.1 rumble } 154 1.1 rumble 155 1.1 rumble static int 156 1.1 rumble oioc_print(void *aux, const char *pnp) 157 1.1 rumble { 158 1.1 rumble struct oioc_attach_args *oa = aux; 159 1.1 rumble 160 1.1 rumble if (pnp) 161 1.1 rumble printf("%s at %s", oa->oa_name, pnp); 162 1.1 rumble 163 1.1 rumble return (UNCONF); 164 1.1 rumble } 165