1 1.19 thorpej /* $NetBSD: pic.c,v 1.19 2021/08/07 16:19:04 thorpej Exp $ */ 2 1.1 sekiya 3 1.1 sekiya /* 4 1.1 sekiya * Copyright (c) 2002 Steve Rumble 5 1.1 sekiya * All rights reserved. 6 1.1 sekiya * 7 1.1 sekiya * Redistribution and use in source and binary forms, with or without 8 1.1 sekiya * modification, are permitted provided that the following conditions 9 1.1 sekiya * are met: 10 1.1 sekiya * 1. Redistributions of source code must retain the above copyright 11 1.1 sekiya * notice, this list of conditions and the following disclaimer. 12 1.1 sekiya * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 sekiya * notice, this list of conditions and the following disclaimer in the 14 1.1 sekiya * documentation and/or other materials provided with the distribution. 15 1.1 sekiya * 3. The name of the author may not be used to endorse or promote products 16 1.1 sekiya * derived from this software without specific prior written permission. 17 1.1 sekiya * 18 1.1 sekiya * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 sekiya * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 sekiya * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 sekiya * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 sekiya * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 sekiya * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 sekiya * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 sekiya * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 sekiya * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 sekiya * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 sekiya */ 29 1.1 sekiya 30 1.7 pooka #include <sys/cdefs.h> 31 1.19 thorpej __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.19 2021/08/07 16:19:04 thorpej Exp $"); 32 1.7 pooka 33 1.1 sekiya #include <sys/param.h> 34 1.1 sekiya #include <sys/device.h> 35 1.1 sekiya #include <sys/systm.h> 36 1.1 sekiya 37 1.1 sekiya #include <machine/cpu.h> 38 1.1 sekiya #include <machine/locore.h> 39 1.1 sekiya #include <machine/autoconf.h> 40 1.15 dyoung #include <sys/bus.h> 41 1.1 sekiya #include <machine/machtype.h> 42 1.2 sekiya #include <machine/sysconf.h> 43 1.1 sekiya 44 1.1 sekiya #include <sgimips/dev/picreg.h> 45 1.1 sekiya 46 1.11 rumble #include <sgimips/gio/giovar.h> 47 1.11 rumble 48 1.1 sekiya #include "locators.h" 49 1.1 sekiya 50 1.1 sekiya struct pic_softc { 51 1.8 rumble bus_space_tag_t iot; 52 1.8 rumble bus_space_handle_t ioh; 53 1.1 sekiya }; 54 1.1 sekiya 55 1.16 chs static int pic_match(device_t, cfdata_t, void *); 56 1.16 chs static void pic_attach(device_t, device_t, void *); 57 1.1 sekiya static int pic_print(void *, const char *); 58 1.8 rumble static void pic_bus_reset(void); 59 1.14 matt static void pic_bus_error(vaddr_t, uint32_t, uint32_t); 60 1.8 rumble static void pic_watchdog_enable(void); 61 1.8 rumble static void pic_watchdog_disable(void); 62 1.8 rumble static void pic_watchdog_tickle(void); 63 1.1 sekiya 64 1.16 chs CFATTACH_DECL_NEW(pic, 0, 65 1.13 tsutsui pic_match, pic_attach, NULL, NULL); 66 1.1 sekiya 67 1.1 sekiya struct pic_attach_args { 68 1.8 rumble const char *iaa_name; 69 1.1 sekiya 70 1.8 rumble bus_space_tag_t iaa_st; 71 1.8 rumble bus_space_handle_t iaa_sh; 72 1.1 sekiya }; 73 1.1 sekiya 74 1.11 rumble int pic_gio32_arb_config(int, uint32_t); 75 1.11 rumble 76 1.1 sekiya static struct pic_softc psc; 77 1.1 sekiya 78 1.1 sekiya static int 79 1.16 chs pic_match(device_t parent, cfdata_t match, void *aux) 80 1.1 sekiya { 81 1.1 sekiya /* 82 1.1 sekiya * PIC exists on IP12 systems. It appears to be the immediate 83 1.1 sekiya * ancestor of the mc, for mips1 processors. 84 1.1 sekiya */ 85 1.4 pooka if (mach_type == MACH_SGI_IP12) 86 1.13 tsutsui return 1; 87 1.4 pooka else 88 1.13 tsutsui return 0; 89 1.1 sekiya } 90 1.1 sekiya 91 1.1 sekiya static void 92 1.16 chs pic_attach(device_t parent, device_t self, void *aux) 93 1.1 sekiya { 94 1.13 tsutsui uint32_t reg; 95 1.1 sekiya struct pic_attach_args iaa; 96 1.1 sekiya struct mainbus_attach_args *ma = aux; 97 1.1 sekiya 98 1.17 macallan psc.iot = normal_memt; 99 1.17 macallan if (bus_space_map(psc.iot, ma->ma_addr, 0x20010, 100 1.1 sekiya BUS_SPACE_MAP_LINEAR, &psc.ioh)) 101 1.1 sekiya panic("pic_attach: could not allocate memory\n"); 102 1.1 sekiya 103 1.2 sekiya platform.bus_reset = pic_bus_reset; 104 1.4 pooka platform.watchdog_enable = pic_watchdog_enable; 105 1.4 pooka platform.watchdog_disable = pic_watchdog_disable; 106 1.3 sekiya platform.watchdog_reset = pic_watchdog_tickle; 107 1.2 sekiya 108 1.1 sekiya reg = bus_space_read_4(psc.iot, psc.ioh, PIC_SYSID); 109 1.1 sekiya reg = (reg >> PIC_SYSID_REVSHIFT) & PIC_SYSID_REVMASK; 110 1.5 pooka printf("\npic0: Revision %c", reg + 64); 111 1.1 sekiya 112 1.1 sekiya /* enable refresh, set big-endian, memory parity, allow slave access */ 113 1.1 sekiya reg = bus_space_read_4(psc.iot, psc.ioh, PIC_CPUCTRL); 114 1.1 sekiya reg |= (PIC_CPUCTRL_REFRESH | PIC_CPUCTRL_BIGENDIAN | PIC_CPUCTRL_MPR | 115 1.1 sekiya PIC_CPUCTRL_SLAVE); 116 1.1 sekiya bus_space_write_4(psc.iot, psc.ioh, PIC_CPUCTRL, reg); 117 1.1 sekiya 118 1.1 sekiya /* query the mode register to see what's going on */ 119 1.1 sekiya reg = bus_space_read_4(psc.iot, psc.ioh, PIC_MODE); 120 1.1 sekiya printf(": dblk (0x%x), iblk (0x%x)\n", reg & PIC_MODE_DBSIZ, 121 1.1 sekiya reg & PIC_MODE_IBSIZ); 122 1.1 sekiya 123 1.9 sekiya /* display the machine type, board revision */ 124 1.9 sekiya printf("pic0: "); 125 1.9 sekiya 126 1.9 sekiya switch (mach_subtype) { 127 1.13 tsutsui case MACH_SGI_IP12_4D_3X: 128 1.13 tsutsui printf("Personal Iris 4D/3x"); 129 1.13 tsutsui break; 130 1.13 tsutsui case MACH_SGI_IP12_VIP12: 131 1.13 tsutsui printf("VME IP12"); 132 1.13 tsutsui break; 133 1.13 tsutsui case MACH_SGI_IP12_HP1: 134 1.13 tsutsui printf("Indigo R3000"); 135 1.13 tsutsui break; 136 1.13 tsutsui case MACH_SGI_IP12_HPLC: 137 1.13 tsutsui printf("Hollywood Light"); 138 1.13 tsutsui break; 139 1.13 tsutsui default: 140 1.13 tsutsui printf("unknown machine"); 141 1.13 tsutsui break; 142 1.9 sekiya } 143 1.9 sekiya printf(", board revision %x\n", mach_boardrev); 144 1.9 sekiya 145 1.8 rumble printf("pic0: "); 146 1.8 rumble 147 1.1 sekiya if (reg & PIC_MODE_NOCACHE) 148 1.8 rumble printf("cache disabled"); 149 1.1 sekiya else 150 1.8 rumble printf("cache enabled"); 151 1.1 sekiya 152 1.1 sekiya if (reg & PIC_MODE_ISTREAM) 153 1.8 rumble printf(", instr streaming"); 154 1.1 sekiya 155 1.1 sekiya if (reg & PIC_MODE_STOREPARTIAL) 156 1.8 rumble printf(", store partial"); 157 1.1 sekiya 158 1.1 sekiya if (reg & PIC_MODE_BUSDRIVE) 159 1.8 rumble printf(", bus drive"); 160 1.1 sekiya 161 1.1 sekiya /* gio32 allow master, real time devices */ 162 1.1 sekiya reg = bus_space_read_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT0); 163 1.1 sekiya reg &= ~(PIC_GIO32ARB_SLOT_SLAVE | PIC_GIO32ARB_SLOT_LONG); 164 1.1 sekiya bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT0, reg); 165 1.1 sekiya 166 1.1 sekiya reg = bus_space_read_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT1); 167 1.1 sekiya reg &= ~(PIC_GIO32ARB_SLOT_SLAVE | PIC_GIO32ARB_SLOT_LONG); 168 1.1 sekiya bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT1, reg); 169 1.1 sekiya 170 1.1 sekiya /* default gio32 burst time */ 171 1.1 sekiya bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_BURST, 172 1.1 sekiya PIC_GIO32ARB_DEFBURST); 173 1.1 sekiya 174 1.1 sekiya /* default gio32 delay time */ 175 1.1 sekiya bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_DELAY, 176 1.1 sekiya PIC_GIO32ARB_DEFDELAY); 177 1.1 sekiya 178 1.1 sekiya printf("\n"); 179 1.1 sekiya 180 1.12 rumble platform.intr5 = pic_bus_error; 181 1.12 rumble 182 1.8 rumble /* 183 1.8 rumble * A GIO bus exists on all IP12's. However, Personal Iris 184 1.8 rumble * machines use VME for their expansion bus. 185 1.8 rumble */ 186 1.1 sekiya iaa.iaa_name = "gio"; 187 1.19 thorpej (void)config_found(self, (void *)&iaa, pic_print, CFARGS_NONE); 188 1.1 sekiya 189 1.8 rumble pic_watchdog_enable(); 190 1.1 sekiya } 191 1.1 sekiya 192 1.1 sekiya 193 1.1 sekiya static int 194 1.1 sekiya pic_print(void *aux, const char *name) 195 1.1 sekiya { 196 1.1 sekiya struct pic_attach_args *iaa = aux; 197 1.1 sekiya 198 1.1 sekiya if (name) 199 1.1 sekiya aprint_normal("%s at %s", iaa->iaa_name, name); 200 1.1 sekiya 201 1.13 tsutsui return UNCONF; 202 1.1 sekiya } 203 1.1 sekiya 204 1.8 rumble static void 205 1.1 sekiya pic_bus_reset(void) 206 1.1 sekiya { 207 1.13 tsutsui 208 1.1 sekiya bus_space_write_4(psc.iot, psc.ioh, PIC_PARITY_ERROR, 0); 209 1.1 sekiya } 210 1.1 sekiya 211 1.8 rumble static void 212 1.14 matt pic_bus_error(vaddr_t pc, uint32_t status, uint32_t ipending) 213 1.12 rumble { 214 1.12 rumble 215 1.12 rumble printf("pic0: bus error\n"); 216 1.12 rumble pic_bus_reset(); 217 1.12 rumble } 218 1.12 rumble 219 1.12 rumble static void 220 1.8 rumble pic_watchdog_enable(void) 221 1.4 pooka { 222 1.4 pooka uint32_t reg; 223 1.4 pooka 224 1.4 pooka reg = bus_space_read_4(psc.iot, psc.ioh, PIC_CPUCTRL); 225 1.4 pooka reg |= PIC_CPUCTRL_WDOG; 226 1.4 pooka bus_space_write_4(psc.iot, psc.ioh, PIC_CPUCTRL, reg); 227 1.4 pooka } 228 1.4 pooka 229 1.8 rumble static void 230 1.8 rumble pic_watchdog_disable(void) 231 1.1 sekiya { 232 1.4 pooka uint32_t reg; 233 1.1 sekiya 234 1.6 pooka reg = bus_space_read_4(psc.iot, psc.ioh, PIC_CPUCTRL); 235 1.4 pooka reg &= ~(PIC_CPUCTRL_WDOG); 236 1.4 pooka bus_space_write_4(psc.iot, psc.ioh, PIC_CPUCTRL, reg); 237 1.4 pooka } 238 1.4 pooka 239 1.8 rumble static void 240 1.8 rumble pic_watchdog_tickle(void) 241 1.4 pooka { 242 1.4 pooka 243 1.8 rumble pic_watchdog_disable(); 244 1.8 rumble pic_watchdog_enable(); 245 1.1 sekiya } 246 1.11 rumble 247 1.11 rumble /* intended to be called from gio/gio.c only */ 248 1.11 rumble int 249 1.11 rumble pic_gio32_arb_config(int slot, uint32_t flags) 250 1.11 rumble { 251 1.11 rumble uint32_t reg; 252 1.11 rumble 253 1.11 rumble /* only Indigo machines have GIO expansion slots (XXX HPLC?) */ 254 1.11 rumble if (mach_subtype != MACH_SGI_IP12_HP1 && 255 1.11 rumble mach_subtype != MACH_SGI_IP12_HPLC) 256 1.13 tsutsui return EINVAL; 257 1.11 rumble 258 1.11 rumble /* graphics slot is not valid on IP12 */ 259 1.11 rumble if (slot != GIO_SLOT_EXP0 && slot != GIO_SLOT_EXP1) 260 1.13 tsutsui return EINVAL; 261 1.11 rumble 262 1.11 rumble reg = bus_space_read_4(psc.iot, psc.ioh, (slot == GIO_SLOT_EXP0) ? 263 1.11 rumble PIC_GIO32ARB_SLOT0 : PIC_GIO32ARB_SLOT1); 264 1.11 rumble 265 1.11 rumble if (flags & GIO_ARB_RT) 266 1.11 rumble reg &= ~PIC_GIO32ARB_SLOT_LONG; 267 1.11 rumble 268 1.11 rumble if (flags & GIO_ARB_LB) 269 1.11 rumble reg |= PIC_GIO32ARB_SLOT_LONG; 270 1.11 rumble 271 1.11 rumble if (flags & GIO_ARB_MST) 272 1.11 rumble reg &= ~PIC_GIO32ARB_SLOT_SLAVE; 273 1.11 rumble 274 1.11 rumble if (flags & GIO_ARB_SLV) 275 1.11 rumble reg |= PIC_GIO32ARB_SLOT_SLAVE; 276 1.11 rumble 277 1.11 rumble bus_space_write_4(psc.iot, psc.ioh, (slot == GIO_SLOT_EXP0) ? 278 1.11 rumble PIC_GIO32ARB_SLOT0 : PIC_GIO32ARB_SLOT1, reg); 279 1.11 rumble 280 1.13 tsutsui return 0; 281 1.11 rumble } 282