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