plumiobus.c revision 1.3
1/* $NetBSD: plumiobus.c,v 1.3 2000/02/27 16:28:13 uch Exp $ */ 2 3/* 4 * Copyright (c) 1999, 2000 by UCHIYAMA Yasushi 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. The name of the developer may NOT be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28#define PLUMIOBUSDEBUG 29#include "opt_tx39_debug.h" 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/device.h> 34#include <sys/malloc.h> 35 36#include <machine/bus.h> 37#include <machine/intr.h> 38 39#include <hpcmips/tx/tx39var.h> 40#include <hpcmips/dev/plumvar.h> 41#include <hpcmips/dev/plumicuvar.h> 42#include <hpcmips/dev/plumpowervar.h> 43#include <hpcmips/dev/plumiobusreg.h> 44#include <hpcmips/dev/plumiobusvar.h> 45 46#include "locators.h" 47 48#ifdef PLUMIOBUSDEBUG 49int plumiobus_debug = 0; 50#define DPRINTF(arg) if (plumiobus_debug) printf arg; 51#define DPRINTFN(n, arg) if (plumiobus_debug > (n)) printf arg; 52#else 53#define DPRINTF(arg) 54#define DPRINTFN(n, arg) 55#endif 56 57int plumiobus_match __P((struct device*, struct cfdata*, void*)); 58void plumiobus_attach __P((struct device*, struct device*, void*)); 59int plumiobus_print __P((void*, const char*)); 60int plumiobus_search __P((struct device*, struct cfdata*, void*)); 61 62struct plumisa_resource { 63 int pr_irq; 64 bus_space_tag_t pr_iot; 65 int pr_enabled; 66}; 67 68struct plumiobus_softc { 69 struct device sc_dev; 70 plum_chipset_tag_t sc_pc; 71 bus_space_tag_t sc_regt; 72 bus_space_handle_t sc_regh; 73 bus_space_tag_t sc_iot; 74 bus_space_handle_t sc_ioh; 75 struct plumisa_resource sc_isa[PLUM_IOBUS_IO5CSMAX]; 76}; 77 78struct cfattach plumiobus_ca = { 79 sizeof(struct plumiobus_softc), plumiobus_match, plumiobus_attach 80}; 81 82bus_space_tag_t __plumiobus_subregion __P((bus_space_tag_t, bus_addr_t, 83 bus_size_t)); 84#ifdef PLUMIOBUSDEBUG 85void plumiobus_dump __P((struct plumiobus_softc*)); 86#endif 87 88int 89plumiobus_match(parent, cf, aux) 90 struct device *parent; 91 struct cfdata *cf; 92 void *aux; 93{ 94 return (1); 95} 96 97void 98plumiobus_attach(parent, self, aux) 99 struct device *parent; 100 struct device *self; 101 void *aux; 102{ 103 struct plum_attach_args *pa = aux; 104 struct plumiobus_softc *sc = (void*)self; 105 struct plumisa_resource *pr; 106 107 sc->sc_pc = pa->pa_pc; 108 sc->sc_regt = pa->pa_regt; 109 sc->sc_iot = pa->pa_iot; 110 111 if (bus_space_map(sc->sc_regt, PLUM_IOBUS_REGBASE, 112 PLUM_IOBUS_REGSIZE, 0, &sc->sc_regh)) { 113 printf(": register map failed.\n"); 114 return; 115 } 116 printf("\n"); 117 plum_power_establish(sc->sc_pc, PLUM_PWR_IO5); 118 119 /* Address space <-> IRQ mapping */ 120 pr = &sc->sc_isa[IO5CS0]; 121 pr->pr_irq = PLUM_INT_EXT5IO0; 122 pr->pr_iot = __plumiobus_subregion( 123 sc->sc_iot, 124 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS0BASE, 125 PLUM_IOBUS_IO5SIZE); 126 127 pr = &sc->sc_isa[IO5CS1]; 128 pr->pr_irq = PLUM_INT_EXT5IO1; 129 pr->pr_iot = __plumiobus_subregion( 130 sc->sc_iot, 131 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS1BASE, 132 PLUM_IOBUS_IO5SIZE); 133 134 pr = &sc->sc_isa[IO5CS2]; 135 pr->pr_irq = PLUM_INT_EXT5IO2; 136 pr->pr_iot = __plumiobus_subregion( 137 sc->sc_iot, 138 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS2BASE, 139 PLUM_IOBUS_IO5SIZE); 140 141 pr = &sc->sc_isa[IO5CS3]; 142 pr->pr_irq = PLUM_INT_EXT5IO3; 143 pr->pr_iot = __plumiobus_subregion( 144 sc->sc_iot, 145 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS3BASE, 146 PLUM_IOBUS_IO5SIZE); 147 148 pr = &sc->sc_isa[IO5CS4]; 149 pr->pr_irq = PLUM_INT_EXT3IO0; /* XXX */ 150 pr->pr_iot = __plumiobus_subregion( 151 sc->sc_iot, 152 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS4BASE, 153 PLUM_IOBUS_IO5SIZE); 154 155 156 pr = &sc->sc_isa[IO5NCS]; 157 pr->pr_irq = PLUM_INT_EXT3IO1; 158 pr->pr_iot = __plumiobus_subregion( 159 sc->sc_iot, 160 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS5BASE, 161 PLUM_IOBUS_IO5SIZE); 162 163#ifdef PLUMIOBUSDEBUG 164 plumiobus_dump(sc); 165#endif 166 167 config_search(plumiobus_search, self, plumiobus_print); 168} 169 170/* XXX something kludge */ 171bus_space_tag_t 172__plumiobus_subregion(t, ofs, size) 173 bus_space_tag_t t; 174 bus_addr_t ofs; 175 bus_size_t size; 176{ 177 struct hpcmips_bus_space *hbs; 178 179 if (!(hbs = malloc(sizeof(struct hpcmips_bus_space), 180 M_DEVBUF, M_NOWAIT))) { 181 panic ("__plumiobus_subregion: no memory."); 182 } 183 *hbs = *t; 184 hbs->t_base += ofs; 185 hbs->t_size = size; 186 187 return (hbs); 188} 189 190int 191plumiobus_search(parent, cf, aux) 192 struct device *parent; 193 struct cfdata *cf; 194 void *aux; 195{ 196 struct plumiobus_softc *sc = (void*)parent; 197 struct plumiobus_attach_args pba; 198 int slot; 199 200 /* Disallow wildcarded IO5CS slot */ 201 if (cf->cf_loc[PLUMIOBUSIFCF_SLOT] == PLUMIOBUSIFCF_SLOT_DEFAULT) { 202 printf("plumiobus_search: wildcarded slot, skipping\n"); 203 return (0); 204 } 205 slot = pba.pba_slot = cf->cf_loc[PLUMIOBUSIFCF_SLOT]; 206 207 pba.pba_pc = sc->sc_pc; 208 pba.pba_iot = sc->sc_isa[slot].pr_iot; 209 pba.pba_irq = sc->sc_isa[slot].pr_irq; 210 pba.pba_busname = "plumisab"; 211 212 if (!(sc->sc_isa[slot].pr_enabled) && /* not attached slot */ 213 (*cf->cf_attach->ca_match)(parent, cf, &pba)) { 214 config_attach(parent, cf, &pba, plumiobus_print); 215 sc->sc_isa[slot].pr_enabled = 1; 216 } 217 218 return (0); 219} 220 221int 222plumiobus_print(aux, pnp) 223 void *aux; 224 const char *pnp; 225{ 226 return (pnp ? QUIET : UNCONF); 227} 228 229#ifdef PLUMIOBUSDEBUG 230void 231plumiobus_dump(sc) 232 struct plumiobus_softc *sc; 233{ 234 bus_space_tag_t regt = sc->sc_regt; 235 bus_space_handle_t regh = sc->sc_regh; 236 plumreg_t reg; 237 int i, wait; 238 239 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXBSZ_REG); 240 printf("8bit port:"); 241 for (i = 0; i < 6; i++) { 242 if (reg & (1 << i)) { 243 printf(" IO5CS%d", i); 244 } 245 } 246 printf("\n"); 247 248 reg = PLUM_IOBUS_IOXCCNT_MASK & 249 plum_conf_read(regt, regh, PLUM_IOBUS_IOXCCNT_REG); 250 printf(" # of wait to become from the access begining: %d clock\n", 251 reg + 1); 252 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXACNT_REG); 253 printf(" # of wait in access clock: "); 254 for (i = 0; i < 5; i++) { 255 wait = (reg >> (i * PLUM_IOBUS_IOXACNT_SHIFT)) 256 & PLUM_IOBUS_IOXACNT_MASK; 257 printf("[CS%d:%d] ", i, wait + 1); 258 } 259 printf("\n"); 260 261 reg = PLUM_IOBUS_IOXSCNT_MASK & 262 plum_conf_read(regt, regh, PLUM_IOBUS_IOXSCNT_REG); 263 printf(" # of wait during access by I/O bus : %d clock\n", reg + 1); 264 265 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IDEMODE_REG); 266 if (reg & PLUM_IOBUS_IDEMODE) { 267 printf("IO5CS3,4 IDE mode\n"); 268 } 269} 270#endif /* PLUMIOBUSDEBUG */ 271