1 /* $NetBSD: clmpcc_pcctwo.c,v 1.1 2002/02/12 20:38:40 scw Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Steve C. Woodford. 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Cirrus Logic CD2401 4-channel serial chip. PCCchip2 Front-end. 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/proc.h> 46 #include <sys/device.h> 47 #include <sys/conf.h> 48 #include <sys/file.h> 49 #include <sys/ioctl.h> 50 #include <sys/tty.h> 51 #include <sys/time.h> 52 #include <sys/kernel.h> 53 #include <sys/syslog.h> 54 55 #include <dev/cons.h> 56 57 #include <machine/cpu.h> 58 #include <machine/bus.h> 59 #include <machine/intr.h> 60 61 #include <dev/ic/clmpccvar.h> 62 63 #include <dev/mvme/pcctwovar.h> 64 #include <dev/mvme/pcctworeg.h> 65 66 /* XXXXSCW: Fixme */ 67 #ifdef MVME68K 68 #include <mvme68k/dev/mainbus.h> 69 #else 70 #error Need consiack hook 71 #endif 72 73 74 /* Definition of the driver for autoconfig. */ 75 int clmpcc_pcctwo_match __P((struct device *, struct cfdata *, void *)); 76 void clmpcc_pcctwo_attach __P((struct device *, struct device *, void *)); 77 void clmpcc_pcctwo_iackhook __P((struct clmpcc_softc *, int)); 78 void clmpcc_pcctwo_consiackhook __P((struct clmpcc_softc *, int)); 79 80 struct cfattach clmpcc_pcctwo_ca = { 81 sizeof(struct clmpcc_softc), clmpcc_pcctwo_match, clmpcc_pcctwo_attach 82 }; 83 84 extern struct cfdriver clmpcc_cd; 85 86 /* 87 * For clmpccopen() and clmpcccn*() 88 */ 89 cdev_decl(clmpcc); 90 cons_decl(clmpcc); 91 92 93 /* 94 * Is the CD2401 chip present? 95 */ 96 int 97 clmpcc_pcctwo_match(parent, cf, aux) 98 struct device *parent; 99 struct cfdata *cf; 100 void *aux; 101 { 102 struct pcctwo_attach_args *pa; 103 104 pa = aux; 105 106 if (strcmp(pa->pa_name, clmpcc_cd.cd_name)) 107 return (0); 108 109 pa->pa_ipl = cf->pcctwocf_ipl; 110 111 return (1); 112 } 113 114 /* 115 * Attach a found CD2401. 116 */ 117 void 118 clmpcc_pcctwo_attach(parent, self, aux) 119 struct device *parent; 120 struct device *self; 121 void *aux; 122 { 123 struct clmpcc_softc *sc; 124 struct pcctwo_attach_args *pa; 125 int level = pa->pa_ipl; 126 127 sc = (struct clmpcc_softc *)self; 128 pa = aux; 129 level = pa->pa_ipl; 130 sc->sc_iot = pa->pa_bust; 131 bus_space_map(pa->pa_bust, pa->pa_offset, 0x100, 0, &sc->sc_ioh); 132 133 sc->sc_clk = 20000000; 134 sc->sc_byteswap = CLMPCC_BYTESWAP_LOW; 135 sc->sc_swaprtsdtr = 1; 136 sc->sc_iackhook = clmpcc_pcctwo_iackhook; 137 sc->sc_vector_base = PCCTWO_SCC_VECBASE; 138 sc->sc_rpilr = 0x03; 139 sc->sc_tpilr = 0x02; 140 sc->sc_mpilr = 0x01; 141 sc->sc_evcnt = pcctwointr_evcnt(level); 142 143 /* Do common parts of CD2401 configuration. */ 144 clmpcc_attach(sc); 145 146 /* Hook the interrupts */ 147 pcctwointr_establish(PCCTWOV_SCC_RX, clmpcc_rxintr, level, sc, NULL); 148 pcctwointr_establish(PCCTWOV_SCC_RX_EXCEP, clmpcc_rxintr, level, sc, 149 NULL); 150 pcctwointr_establish(PCCTWOV_SCC_TX, clmpcc_txintr, level, sc, NULL); 151 pcctwointr_establish(PCCTWOV_SCC_MODEM, clmpcc_mdintr, level, sc, NULL); 152 } 153 154 void 155 clmpcc_pcctwo_iackhook(sc, which) 156 struct clmpcc_softc *sc; 157 int which; 158 { 159 bus_size_t offset; 160 volatile u_char foo; 161 162 switch (which) { 163 case CLMPCC_IACK_MODEM: 164 offset = PCC2REG_SCC_MODEM_PIACK; 165 break; 166 167 case CLMPCC_IACK_RX: 168 offset = PCC2REG_SCC_RX_PIACK; 169 break; 170 171 case CLMPCC_IACK_TX: 172 offset = PCC2REG_SCC_TX_PIACK; 173 break; 174 #ifdef DEBUG 175 default: 176 printf("%s: Invalid IACK number '%d'\n", 177 sc->sc_dev.dv_xname, which); 178 panic("clmpcc_pcctwo_iackhook"); 179 #endif 180 } 181 182 foo = pcc2_reg_read(sys_pcctwo, offset); 183 } 184 185 /* 186 * This routine is only used prior to clmpcc_attach() being called 187 */ 188 void 189 clmpcc_pcctwo_consiackhook(sc, which) 190 struct clmpcc_softc *sc; 191 int which; 192 { 193 bus_space_handle_t bush; 194 bus_size_t offset; 195 volatile u_char foo; 196 197 switch (which) { 198 case CLMPCC_IACK_MODEM: 199 offset = PCC2REG_SCC_MODEM_PIACK; 200 break; 201 202 case CLMPCC_IACK_RX: 203 offset = PCC2REG_SCC_RX_PIACK; 204 break; 205 206 case CLMPCC_IACK_TX: 207 offset = PCC2REG_SCC_TX_PIACK; 208 break; 209 #ifdef DEBUG 210 default: 211 printf("%s: Invalid IACK number '%d'\n", 212 sc->sc_dev.dv_xname, which); 213 panic("clmpcc_pcctwo_consiackhook"); 214 #endif 215 } 216 217 #ifdef MVME68K 218 /* 219 * We need to fake the tag and handle since 'sys_pcctwo' will 220 * be NULL during early system startup... 221 */ 222 bush = (bus_space_handle_t) & (intiobase[MAINBUS_PCCTWO_OFFSET + 223 PCCTWO_REG_OFF]); 224 225 foo = bus_space_read_1(&_mainbus_space_tag, bush, offset); 226 #else 227 #error Need consiack hook 228 #endif 229 } 230 231 232 /**************************************************************** 233 * Console support functions (MVME PCCchip2 specific!) 234 ****************************************************************/ 235 236 /* 237 * Check for CD2401 console. 238 */ 239 void 240 clmpcccnprobe(cp) 241 struct consdev *cp; 242 { 243 int maj; 244 245 #if defined(MVME68K) 246 if (machineid != MVME_167 && machineid != MVME_177) 247 #elif defined(MVME88K) 248 if (machineid != MVME_187) 249 #endif 250 { 251 cp->cn_pri = CN_DEAD; 252 return; 253 } 254 255 /* 256 * Locate the major number 257 */ 258 for (maj = 0; maj < nchrdev; maj++) { 259 if (cdevsw[maj].d_open == clmpccopen) 260 break; 261 } 262 263 /* Initialize required fields. */ 264 cp->cn_dev = makedev(maj, 0); 265 cp->cn_pri = CN_NORMAL; 266 } 267 268 void 269 clmpcccninit(cp) 270 struct consdev *cp; 271 { 272 static struct clmpcc_softc cons_sc; 273 274 cons_sc.sc_iot = &_mainbus_space_tag; 275 bus_space_map(&_mainbus_space_tag, 276 intiobase_phys + MAINBUS_PCCTWO_OFFSET + PCCTWO_SCC_OFF, 277 PCC2REG_SIZE, 0, &cons_sc.sc_ioh); 278 cons_sc.sc_clk = 20000000; 279 cons_sc.sc_byteswap = CLMPCC_BYTESWAP_LOW; 280 cons_sc.sc_swaprtsdtr = 1; 281 cons_sc.sc_iackhook = clmpcc_pcctwo_consiackhook; 282 cons_sc.sc_vector_base = PCCTWO_SCC_VECBASE; 283 cons_sc.sc_rpilr = 0x03; 284 cons_sc.sc_tpilr = 0x02; 285 cons_sc.sc_mpilr = 0x01; 286 287 clmpcc_cnattach(&cons_sc, 0, 9600); 288 } 289