1 /* $NetBSD: plum.c,v 1.1 1999/11/21 06:50:26 uch Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 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 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/tx/txcsbusvar.h> 41 #include <hpcmips/dev/plumvar.h> 42 #include <hpcmips/dev/plumreg.h> 43 44 int plum_match __P((struct device*, struct cfdata*, void*)); 45 void plum_attach __P((struct device*, struct device*, void*)); 46 int plum_print __P((void*, const char*)); 47 int plum_search __P((struct device*, struct cfdata*, void*)); 48 49 struct plum_softc { 50 struct device sc_dev; 51 plum_chipset_tag_t sc_pc; 52 bus_space_tag_t sc_csregt; 53 bus_space_tag_t sc_csiot; 54 bus_space_tag_t sc_csmemt; 55 int sc_irq; 56 int sc_pri; 57 }; 58 59 struct cfattach plum_ca = { 60 sizeof(struct plum_softc), plum_match, plum_attach 61 }; 62 63 plumreg_t plum_idcheck __P((bus_space_tag_t)); 64 65 int 66 plum_match(parent, cf, aux) 67 struct device *parent; 68 struct cfdata *cf; 69 void *aux; 70 { 71 struct cs_attach_args *ca = aux; 72 73 switch (plum_idcheck(ca->ca_csreg.cstag)) { 74 default: 75 return 0; 76 case PLUM2_1: 77 case PLUM2_2: 78 } 79 80 return 1; 81 } 82 83 void 84 plum_attach(parent, self, aux) 85 struct device *parent; 86 struct device *self; 87 void *aux; 88 { 89 struct cs_attach_args *ca = aux; 90 struct plum_softc *sc = (void*)self; 91 plumreg_t reg; 92 93 sc->sc_csregt = ca->ca_csreg.cstag; 94 sc->sc_csiot = ca->ca_csio.cstag; 95 sc->sc_csmemt = ca->ca_csmem.cstag; 96 sc->sc_irq = ca->ca_irq1; 97 98 switch (plum_idcheck(sc->sc_csregt)) { 99 default: 100 printf(": unknown revision %#x\n", reg); 101 return; 102 case PLUM2_1: 103 printf(": Plum2 #1\n"); 104 break; 105 case PLUM2_2: 106 printf(": Plum2 #2\n"); 107 break; 108 } 109 if (!(sc->sc_pc = malloc(sizeof(struct plum_chipset_tag), 110 M_DEVBUF, M_NOWAIT))) { 111 panic("no memory"); 112 } 113 memset(sc->sc_pc, 0, sizeof(struct plum_chipset_tag)); 114 sc->sc_pc->pc_tc = ca->ca_tc; 115 116 /* Attach Plum devices */ 117 /* 118 * interrupt, power/clock module is used by other plum module. 119 * attach first. 120 */ 121 sc->sc_pri = 2; 122 config_search(plum_search, self, plum_print); 123 /* 124 * Other plum module. 125 */ 126 sc->sc_pri = 1; 127 config_search(plum_search, self, plum_print); 128 } 129 130 plumreg_t 131 plum_idcheck(regt) 132 bus_space_tag_t regt; 133 { 134 bus_space_handle_t regh; 135 plumreg_t reg; 136 137 if (bus_space_map(regt, PLUM_ID_REGBASE, 138 PLUM_ID_REGSIZE, 0, ®h)) { 139 printf("ID register map failed\n"); 140 return 0; 141 } 142 reg = plum_conf_read(regt, regh, PLUM_ID_REG); 143 bus_space_unmap(regt, regh, PLUM_ID_REGSIZE); 144 145 return reg; 146 } 147 148 int 149 plum_print(aux, pnp) 150 void *aux; 151 const char *pnp; 152 { 153 return pnp ? QUIET : UNCONF; 154 } 155 156 int 157 plum_search(parent, cf, aux) 158 struct device *parent; 159 struct cfdata *cf; 160 void *aux; 161 { 162 struct plum_softc *sc = (void*)parent; 163 struct plum_attach_args pa; 164 165 pa.pa_pc = sc->sc_pc; 166 pa.pa_regt = sc->sc_csregt; 167 pa.pa_iot = sc->sc_csiot; 168 pa.pa_memt = sc->sc_csmemt; 169 pa.pa_irq = sc->sc_irq; 170 171 if ((*cf->cf_attach->ca_match)(parent, cf, &pa) == sc->sc_pri) { 172 config_attach(parent, cf, &pa, plum_print); 173 } 174 175 return 0; 176 } 177 178 plumreg_t 179 plum_conf_read(t, h, o) 180 bus_space_tag_t t; 181 bus_space_handle_t h; 182 int o; 183 { 184 plumreg_t reg; 185 reg = bus_space_read_4(t, h, o); 186 return reg; 187 } 188 189 void 190 plum_conf_write(t, h, o, v) 191 bus_space_tag_t t; 192 bus_space_handle_t h; 193 int o; 194 plumreg_t v; 195 { 196 bus_space_write_4(t, h, o, v); 197 } 198 199 void 200 plum_conf_register_intr(t, intrt) 201 plum_chipset_tag_t t; 202 void *intrt; 203 { 204 if (t->pc_intrt) { 205 panic("duplicate intrt"); 206 } 207 t->pc_intrt = intrt; 208 } 209 210 void 211 plum_conf_register_power(t, powert) 212 plum_chipset_tag_t t; 213 void *powert; 214 { 215 if (t->pc_powert) { 216 panic("duplicate powert"); 217 } 218 t->pc_powert = powert; 219 } 220