Home | History | Annotate | Line # | Download | only in mvme
      1 /*	$NetBSD: pcctwo.c,v 1.13 2021/08/07 16:19:13 thorpej 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  *
     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 /*
     33  * PCCchip2 and MCchip Driver
     34  */
     35 
     36 #include <sys/cdefs.h>
     37 __KERNEL_RCSID(0, "$NetBSD: pcctwo.c,v 1.13 2021/08/07 16:19:13 thorpej Exp $");
     38 
     39 #include <sys/param.h>
     40 #include <sys/kernel.h>
     41 #include <sys/systm.h>
     42 #include <sys/device.h>
     43 
     44 #include <sys/cpu.h>
     45 #include <sys/bus.h>
     46 
     47 #include <dev/mvme/pcctworeg.h>
     48 #include <dev/mvme/pcctwovar.h>
     49 
     50 /*
     51  * Global Pointer to the PCCChip2/MCchip soft state, and chip ID
     52  */
     53 struct pcctwo_softc *sys_pcctwo;
     54 
     55 int pcctwoprint(void *, const char *);
     56 
     57 
     58 /* ARGSUSED */
     59 void
     60 pcctwo_init(struct pcctwo_softc *sc, const struct pcctwo_device *pd, int devoff)
     61 {
     62 	struct pcctwo_attach_args npa;
     63 	u_int8_t cid;
     64 
     65 	/*
     66 	 * Fix up the vector base for PCCChip2 Interrupts
     67 	 */
     68 	pcc2_reg_write(sc, PCC2REG_VECTOR_BASE, sc->sc_vecbase);
     69 
     70 	/*
     71 	 * Enable PCCChip2 Interrupts
     72 	 */
     73 	pcc2_reg_write(sc, PCC2REG_GENERAL_CONTROL,
     74 	    pcc2_reg_read(sc, PCC2REG_GENERAL_CONTROL) | PCCTWO_GEN_CTRL_MIEN);
     75 
     76 	/* What are we? */
     77 	cid = pcc2_reg_read(sc, PCC2REG_CHIP_ID);
     78 
     79 	/*
     80 	 * Announce ourselves to the world in general
     81 	 */
     82 	if (cid == PCCTWO_CHIP_ID_PCC2)
     83 		printf(": Peripheral Channel Controller (PCCchip2), Rev %d\n",
     84 		    pcc2_reg_read(sc, PCC2REG_CHIP_REVISION));
     85 	else
     86 	if (cid == PCCTWO_CHIP_ID_MCCHIP)
     87 		printf(": Memory Controller ASIC (MCchip), Rev %d\n",
     88 		    pcc2_reg_read(sc, PCC2REG_CHIP_REVISION));
     89 
     90 	/*
     91 	 * Attach configured children.
     92 	 */
     93 	npa._pa_base = devoff;
     94 	while (pd->pcc_name != NULL) {
     95 		/*
     96 		 * Note that IPL is filled in by match function.
     97 		 */
     98 		npa.pa_name = pd->pcc_name;
     99 		npa.pa_ipl = -1;
    100 		npa.pa_dmat = sc->sc_dmat;
    101 		npa.pa_bust = sc->sc_bust;
    102 		npa.pa_offset = pd->pcc_offset + devoff;
    103 		pd++;
    104 
    105 		/* Attach the device if configured. */
    106 		(void) config_found(sc->sc_dev, &npa, pcctwoprint, CFARGS_NONE);
    107 	}
    108 }
    109 
    110 int
    111 pcctwoprint(void *aux, const char *cp)
    112 {
    113 	struct pcctwo_attach_args *pa;
    114 
    115 	pa = aux;
    116 
    117 	if (cp)
    118 		aprint_normal("%s at %s", pa->pa_name, cp);
    119 
    120 	aprint_normal(" offset 0x%lx", pa->pa_offset - pa->_pa_base);
    121 	if (pa->pa_ipl != -1)
    122 		aprint_normal(" ipl %d", pa->pa_ipl);
    123 
    124 	return (UNCONF);
    125 }
    126 
    127 /*
    128  * pcctwointr_establish: Establish PCCChip2 Interrupt
    129  */
    130 void
    131 pcctwointr_establish(
    132 	int vec,
    133 	int (*hand)(void *),
    134 	int lvl,
    135 	void *arg,
    136 	struct evcnt *evcnt)
    137 {
    138 	int vec2icsr;
    139 
    140 #ifdef DEBUG
    141 	if (vec < 0 || vec >= PCCTWOV_MAX) {
    142 		printf("pcctwo: illegal vector offset: 0x%x\n", vec);
    143 		panic("pcctwointr_establish");
    144 	}
    145 	if (lvl < 1 || lvl > 7) {
    146 		printf("pcctwo: illegal interrupt level: %d\n", lvl);
    147 		panic("pcctwointr_establish");
    148 	}
    149 	if (sys_pcctwo->sc_vec2icsr[vec] == -1) {
    150 		printf("pcctwo: unsupported vector: %d\n", vec);
    151 		panic("pcctwointr_establish");
    152 	}
    153 #endif
    154 
    155 	vec2icsr = sys_pcctwo->sc_vec2icsr[vec];
    156 	pcc2_reg_write(sys_pcctwo, VEC2ICSR_REG(vec2icsr), 0);
    157 
    158 	/* Hook the interrupt */
    159 	(*sys_pcctwo->sc_isrlink)(sys_pcctwo->sc_isrcookie, hand, arg,
    160 	    lvl, vec + sys_pcctwo->sc_vecbase, evcnt);
    161 
    162 	/* Enable it in hardware */
    163 	pcc2_reg_write(sys_pcctwo, VEC2ICSR_REG(vec2icsr),
    164 	    VEC2ICSR_INIT(vec2icsr) | lvl);
    165 }
    166 
    167 void
    168 pcctwointr_disestablish(int vec)
    169 {
    170 
    171 #ifdef DEBUG
    172 	if (vec < 0 || vec >= PCCTWOV_MAX) {
    173 		printf("pcctwo: illegal vector offset: 0x%x\n", vec);
    174 		panic("pcctwointr_disestablish");
    175 	}
    176 	if (sys_pcctwo->sc_vec2icsr[vec] == -1) {
    177 		printf("pcctwo: unsupported vector: %d\n", vec);
    178 		panic("pcctwointr_establish");
    179 	}
    180 #endif
    181 
    182 	/* Disable it in hardware */
    183 	pcc2_reg_write(sys_pcctwo, sys_pcctwo->sc_vec2icsr[vec], 0);
    184 
    185 	(*sys_pcctwo->sc_isrunlink)(sys_pcctwo->sc_isrcookie,
    186 	    vec + sys_pcctwo->sc_vecbase);
    187 }
    188 
    189 struct evcnt *
    190 pcctwointr_evcnt(int lev)
    191 {
    192 
    193 	return ((*sys_pcctwo->sc_isrevcnt)(sys_pcctwo->sc_isrcookie, lev));
    194 }
    195