1/* $NetBSD: pic.c,v 1.19 2021/08/07 16:19:04 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 2002 Steve Rumble 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/cdefs.h> 31__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.19 2021/08/07 16:19:04 thorpej Exp $"); 32 33#include <sys/param.h> 34#include <sys/device.h> 35#include <sys/systm.h> 36 37#include <machine/cpu.h> 38#include <machine/locore.h> 39#include <machine/autoconf.h> 40#include <sys/bus.h> 41#include <machine/machtype.h> 42#include <machine/sysconf.h> 43 44#include <sgimips/dev/picreg.h> 45 46#include <sgimips/gio/giovar.h> 47 48#include "locators.h" 49 50struct pic_softc { 51 bus_space_tag_t iot; 52 bus_space_handle_t ioh; 53}; 54 55static int pic_match(device_t, cfdata_t, void *); 56static void pic_attach(device_t, device_t, void *); 57static int pic_print(void *, const char *); 58static void pic_bus_reset(void); 59static void pic_bus_error(vaddr_t, uint32_t, uint32_t); 60static void pic_watchdog_enable(void); 61static void pic_watchdog_disable(void); 62static void pic_watchdog_tickle(void); 63 64CFATTACH_DECL_NEW(pic, 0, 65 pic_match, pic_attach, NULL, NULL); 66 67struct pic_attach_args { 68 const char *iaa_name; 69 70 bus_space_tag_t iaa_st; 71 bus_space_handle_t iaa_sh; 72}; 73 74int pic_gio32_arb_config(int, uint32_t); 75 76static struct pic_softc psc; 77 78static int 79pic_match(device_t parent, cfdata_t match, void *aux) 80{ 81 /* 82 * PIC exists on IP12 systems. It appears to be the immediate 83 * ancestor of the mc, for mips1 processors. 84 */ 85 if (mach_type == MACH_SGI_IP12) 86 return 1; 87 else 88 return 0; 89} 90 91static void 92pic_attach(device_t parent, device_t self, void *aux) 93{ 94 uint32_t reg; 95 struct pic_attach_args iaa; 96 struct mainbus_attach_args *ma = aux; 97 98 psc.iot = normal_memt; 99 if (bus_space_map(psc.iot, ma->ma_addr, 0x20010, 100 BUS_SPACE_MAP_LINEAR, &psc.ioh)) 101 panic("pic_attach: could not allocate memory\n"); 102 103 platform.bus_reset = pic_bus_reset; 104 platform.watchdog_enable = pic_watchdog_enable; 105 platform.watchdog_disable = pic_watchdog_disable; 106 platform.watchdog_reset = pic_watchdog_tickle; 107 108 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_SYSID); 109 reg = (reg >> PIC_SYSID_REVSHIFT) & PIC_SYSID_REVMASK; 110 printf("\npic0: Revision %c", reg + 64); 111 112 /* enable refresh, set big-endian, memory parity, allow slave access */ 113 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_CPUCTRL); 114 reg |= (PIC_CPUCTRL_REFRESH | PIC_CPUCTRL_BIGENDIAN | PIC_CPUCTRL_MPR | 115 PIC_CPUCTRL_SLAVE); 116 bus_space_write_4(psc.iot, psc.ioh, PIC_CPUCTRL, reg); 117 118 /* query the mode register to see what's going on */ 119 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_MODE); 120 printf(": dblk (0x%x), iblk (0x%x)\n", reg & PIC_MODE_DBSIZ, 121 reg & PIC_MODE_IBSIZ); 122 123 /* display the machine type, board revision */ 124 printf("pic0: "); 125 126 switch (mach_subtype) { 127 case MACH_SGI_IP12_4D_3X: 128 printf("Personal Iris 4D/3x"); 129 break; 130 case MACH_SGI_IP12_VIP12: 131 printf("VME IP12"); 132 break; 133 case MACH_SGI_IP12_HP1: 134 printf("Indigo R3000"); 135 break; 136 case MACH_SGI_IP12_HPLC: 137 printf("Hollywood Light"); 138 break; 139 default: 140 printf("unknown machine"); 141 break; 142 } 143 printf(", board revision %x\n", mach_boardrev); 144 145 printf("pic0: "); 146 147 if (reg & PIC_MODE_NOCACHE) 148 printf("cache disabled"); 149 else 150 printf("cache enabled"); 151 152 if (reg & PIC_MODE_ISTREAM) 153 printf(", instr streaming"); 154 155 if (reg & PIC_MODE_STOREPARTIAL) 156 printf(", store partial"); 157 158 if (reg & PIC_MODE_BUSDRIVE) 159 printf(", bus drive"); 160 161 /* gio32 allow master, real time devices */ 162 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT0); 163 reg &= ~(PIC_GIO32ARB_SLOT_SLAVE | PIC_GIO32ARB_SLOT_LONG); 164 bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT0, reg); 165 166 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT1); 167 reg &= ~(PIC_GIO32ARB_SLOT_SLAVE | PIC_GIO32ARB_SLOT_LONG); 168 bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_SLOT1, reg); 169 170 /* default gio32 burst time */ 171 bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_BURST, 172 PIC_GIO32ARB_DEFBURST); 173 174 /* default gio32 delay time */ 175 bus_space_write_4(psc.iot, psc.ioh, PIC_GIO32ARB_DELAY, 176 PIC_GIO32ARB_DEFDELAY); 177 178 printf("\n"); 179 180 platform.intr5 = pic_bus_error; 181 182 /* 183 * A GIO bus exists on all IP12's. However, Personal Iris 184 * machines use VME for their expansion bus. 185 */ 186 iaa.iaa_name = "gio"; 187 (void)config_found(self, (void *)&iaa, pic_print, CFARGS_NONE); 188 189 pic_watchdog_enable(); 190} 191 192 193static int 194pic_print(void *aux, const char *name) 195{ 196 struct pic_attach_args *iaa = aux; 197 198 if (name) 199 aprint_normal("%s at %s", iaa->iaa_name, name); 200 201 return UNCONF; 202} 203 204static void 205pic_bus_reset(void) 206{ 207 208 bus_space_write_4(psc.iot, psc.ioh, PIC_PARITY_ERROR, 0); 209} 210 211static void 212pic_bus_error(vaddr_t pc, uint32_t status, uint32_t ipending) 213{ 214 215 printf("pic0: bus error\n"); 216 pic_bus_reset(); 217} 218 219static void 220pic_watchdog_enable(void) 221{ 222 uint32_t reg; 223 224 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_CPUCTRL); 225 reg |= PIC_CPUCTRL_WDOG; 226 bus_space_write_4(psc.iot, psc.ioh, PIC_CPUCTRL, reg); 227} 228 229static void 230pic_watchdog_disable(void) 231{ 232 uint32_t reg; 233 234 reg = bus_space_read_4(psc.iot, psc.ioh, PIC_CPUCTRL); 235 reg &= ~(PIC_CPUCTRL_WDOG); 236 bus_space_write_4(psc.iot, psc.ioh, PIC_CPUCTRL, reg); 237} 238 239static void 240pic_watchdog_tickle(void) 241{ 242 243 pic_watchdog_disable(); 244 pic_watchdog_enable(); 245} 246 247/* intended to be called from gio/gio.c only */ 248int 249pic_gio32_arb_config(int slot, uint32_t flags) 250{ 251 uint32_t reg; 252 253 /* only Indigo machines have GIO expansion slots (XXX HPLC?) */ 254 if (mach_subtype != MACH_SGI_IP12_HP1 && 255 mach_subtype != MACH_SGI_IP12_HPLC) 256 return EINVAL; 257 258 /* graphics slot is not valid on IP12 */ 259 if (slot != GIO_SLOT_EXP0 && slot != GIO_SLOT_EXP1) 260 return EINVAL; 261 262 reg = bus_space_read_4(psc.iot, psc.ioh, (slot == GIO_SLOT_EXP0) ? 263 PIC_GIO32ARB_SLOT0 : PIC_GIO32ARB_SLOT1); 264 265 if (flags & GIO_ARB_RT) 266 reg &= ~PIC_GIO32ARB_SLOT_LONG; 267 268 if (flags & GIO_ARB_LB) 269 reg |= PIC_GIO32ARB_SLOT_LONG; 270 271 if (flags & GIO_ARB_MST) 272 reg &= ~PIC_GIO32ARB_SLOT_SLAVE; 273 274 if (flags & GIO_ARB_SLV) 275 reg |= PIC_GIO32ARB_SLOT_SLAVE; 276 277 bus_space_write_4(psc.iot, psc.ioh, (slot == GIO_SLOT_EXP0) ? 278 PIC_GIO32ARB_SLOT0 : PIC_GIO32ARB_SLOT1, reg); 279 280 return 0; 281} 282