Home | History | Annotate | Line # | Download | only in vr
      1  1.11   thorpej /* $NetBSD: vrecu.c,v 1.11 2023/12/20 14:50:02 thorpej Exp $ */
      2   1.1       igy 
      3   1.1       igy /*
      4   1.1       igy  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      5   1.1       igy  * All rights reserved.
      6   1.1       igy  *
      7   1.1       igy  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1       igy  * by Naoto Shimazaki of YOKOGAWA Electric Corporation.
      9   1.1       igy  *
     10   1.1       igy  * Redistribution and use in source and binary forms, with or without
     11   1.1       igy  * modification, are permitted provided that the following conditions
     12   1.1       igy  * are met:
     13   1.1       igy  * 1. Redistributions of source code must retain the above copyright
     14   1.1       igy  *    notice, this list of conditions and the following disclaimer.
     15   1.1       igy  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1       igy  *    notice, this list of conditions and the following disclaimer in the
     17   1.1       igy  *    documentation and/or other materials provided with the distribution.
     18   1.1       igy  *
     19   1.1       igy  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1       igy  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1       igy  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1       igy  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1       igy  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1       igy  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1       igy  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1       igy  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1       igy  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1       igy  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1       igy  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1       igy  */
     31   1.2     lukem 
     32   1.2     lukem #include <sys/cdefs.h>
     33  1.11   thorpej __KERNEL_RCSID(0, "$NetBSD: vrecu.c,v 1.11 2023/12/20 14:50:02 thorpej Exp $");
     34   1.1       igy 
     35   1.1       igy #include <sys/param.h>
     36   1.1       igy #include <sys/device.h>
     37   1.1       igy #include <sys/queue.h>
     38   1.1       igy #include <sys/systm.h>
     39   1.1       igy 
     40   1.1       igy #include <machine/bus.h>
     41   1.1       igy #include <machine/intr.h>
     42   1.1       igy 
     43   1.1       igy #include <hpcmips/vr/vrcpudef.h>
     44   1.1       igy #include <hpcmips/vr/vripif.h>
     45   1.1       igy #include <hpcmips/vr/vr4181ecureg.h>
     46   1.1       igy 
     47   1.1       igy #include <dev/isa/isareg.h>
     48   1.1       igy #include <dev/isa/isavar.h>
     49   1.1       igy #include <dev/pcmcia/pcmciareg.h>
     50   1.1       igy #include <dev/pcmcia/pcmciavar.h>
     51   1.1       igy #include <dev/pcmcia/pcmciachip.h>
     52   1.1       igy 
     53   1.1       igy #include <dev/ic/i82365reg.h>
     54   1.1       igy #include <dev/ic/i82365var.h>
     55   1.1       igy #include <dev/isa/i82365_isavar.h>
     56   1.1       igy 
     57  1.10       chs static int pcic_vrip_match(device_t, cfdata_t, void *);
     58  1.10       chs static void pcic_vrip_attach(device_t, device_t, void *);
     59   1.1       igy static void *pcic_vrip_chip_intr_establish(pcmcia_chipset_handle_t,
     60   1.1       igy 					   struct pcmcia_function *, int,
     61   1.1       igy 					   int (*)(void *), void *);
     62   1.1       igy static void pcic_vrip_chip_intr_disestablish(pcmcia_chipset_handle_t, void *);
     63   1.1       igy static int pcic_vrip_intr(void *);
     64   1.1       igy 
     65   1.1       igy struct pcic_vrip_softc {
     66   1.1       igy 	struct pcic_softc	sc_pcic;	/* real pcic softc */
     67   1.8   tsutsui 	uint16_t		sc_intr_mask;
     68   1.8   tsutsui 	uint16_t		sc_intr_valid;
     69   1.1       igy 	struct intrhand {
     70   1.1       igy 		int	(*ih_fun)(void *);
     71   1.1       igy 		void	*ih_arg;
     72   1.1       igy 	} 			sc_intrhand[ECU_MAX_INTR];
     73   1.1       igy };
     74   1.1       igy 
     75  1.10       chs CFATTACH_DECL_NEW(pcic_vrip, sizeof(struct pcic_vrip_softc),
     76   1.1       igy 	      pcic_vrip_match, pcic_vrip_attach, NULL, NULL);
     77   1.1       igy 
     78   1.1       igy static struct pcmcia_chip_functions pcic_vrip_functions = {
     79   1.1       igy 	.mem_alloc		= pcic_chip_mem_alloc,
     80   1.1       igy 	.mem_free		= pcic_chip_mem_free,
     81   1.1       igy 	.mem_map		= pcic_chip_mem_map,
     82   1.1       igy 	.mem_unmap		= pcic_chip_mem_unmap,
     83   1.1       igy 
     84   1.1       igy 	.io_alloc		= pcic_chip_io_alloc,
     85   1.1       igy 	.io_free		= pcic_chip_io_free,
     86   1.1       igy 	.io_map			= pcic_chip_io_map,
     87   1.1       igy 	.io_unmap		= pcic_chip_io_unmap,
     88   1.1       igy 
     89   1.1       igy 	.intr_establish		= pcic_vrip_chip_intr_establish,
     90   1.1       igy 	.intr_disestablish	= pcic_vrip_chip_intr_disestablish,
     91   1.1       igy 
     92   1.1       igy 	.socket_enable		= pcic_chip_socket_enable,
     93   1.1       igy 	.socket_disable		= pcic_chip_socket_disable,
     94   1.4   mycroft 	.socket_settype		= pcic_chip_socket_settype,
     95   1.1       igy };
     96   1.1       igy 
     97   1.1       igy 
     98   1.1       igy static int
     99  1.10       chs pcic_vrip_match(device_t parent, cfdata_t match, void *aux)
    100   1.1       igy {
    101   1.1       igy 	return 1;
    102   1.1       igy }
    103   1.1       igy 
    104   1.1       igy static void
    105  1.10       chs pcic_vrip_attach(device_t parent, device_t self, void *aux)
    106   1.1       igy {
    107   1.9   tsutsui 	struct pcic_vrip_softc	*vsc = device_private(self);
    108   1.9   tsutsui 	struct pcic_softc	*sc = &vsc->sc_pcic;
    109   1.1       igy 	struct vrip_attach_args	*va = aux;
    110   1.1       igy 	bus_space_handle_t	ioh;
    111   1.1       igy 	bus_space_handle_t	memh;
    112   1.1       igy 	int			i;
    113   1.1       igy 
    114  1.10       chs 	sc->dev = self;
    115   1.1       igy 	vsc->sc_intr_valid = PCIC_INTR_IRQ_VALIDMASK;
    116   1.1       igy 	vsc->sc_intr_mask = 0xffff;
    117   1.1       igy 	for (i = 0; i < ECU_MAX_INTR; i++)
    118   1.1       igy 		vsc->sc_intrhand[i].ih_fun = NULL;
    119   1.1       igy 
    120   1.1       igy 	if ((sc->ih = vrip_intr_establish(va->va_vc, va->va_unit, 0,
    121   1.9   tsutsui 					  IPL_NET, pcic_vrip_intr, vsc))
    122   1.1       igy 	    == NULL) {
    123   1.9   tsutsui 		printf(": can't establish interrupt");
    124   1.1       igy 	}
    125   1.1       igy 
    126   1.1       igy         /* Map i/o space. */
    127   1.1       igy         if (bus_space_map(va->va_iot, va->va_addr, ECU_SIZE, 0, &ioh)) {
    128   1.1       igy                 printf(": can't map pcic register space\n");
    129   1.1       igy                 return;
    130   1.1       igy         }
    131   1.1       igy 
    132   1.1       igy 	/* init CFG_REG_1 */
    133   1.1       igy 	bus_space_write_2(va->va_iot, ioh, ECU_CFG_REG_1_W, 0x0001);
    134   1.1       igy 
    135   1.1       igy 	/* mask all interrupt */
    136   1.1       igy 	bus_space_write_2(va->va_iot, ioh, ECU_INTMSK_REG_W,
    137   1.1       igy 			  vsc->sc_intr_mask);
    138   1.1       igy 
    139   1.1       igy 	/* Map mem space. */
    140   1.1       igy #if 1
    141   1.1       igy 	if (bus_space_map(va->va_iot, VR_ISA_MEM_BASE, 0x4000, 0, &memh))
    142   1.1       igy 		panic("pcic_pci_attach: can't map mem space");
    143   1.1       igy 
    144   1.1       igy 	sc->membase = VR_ISA_MEM_BASE;
    145   1.1       igy 	sc->subregionmask = (1 << (0x4000 / PCIC_MEM_PAGESIZE)) - 1;
    146   1.1       igy 
    147   1.1       igy 	sc->iobase = VR_ISA_PORT_BASE + 0x400;
    148   1.1       igy 	sc->iosize = 0xbff;
    149   1.1       igy #else
    150   1.1       igy 	if (bus_space_map(va->va_iot, VR_ISA_MEM_BASE, 0x70000, 0, &memh))
    151   1.1       igy 		panic("pcic_pci_attach: can't map mem space");
    152   1.1       igy 
    153   1.1       igy 	sc->membase = VR_ISA_MEM_BASE;
    154   1.1       igy 	sc->subregionmask = (1 << (0x70000 / PCIC_MEM_PAGESIZE)) - 1;
    155   1.1       igy 
    156   1.1       igy 	sc->iobase = VR_ISA_PORT_BASE;
    157   1.1       igy 	sc->iosize = 0x10000;
    158   1.1       igy #endif
    159   1.1       igy 
    160   1.1       igy 	sc->pct = &pcic_vrip_functions;
    161   1.1       igy 
    162   1.1       igy 	sc->iot = va->va_iot;
    163   1.1       igy 	sc->ioh = ioh;
    164   1.1       igy 	sc->memt = va->va_iot;
    165   1.1       igy 	sc->memh = memh;
    166   1.1       igy 
    167   1.1       igy 	printf("\n");
    168   1.1       igy 
    169   1.5  drochner 	sc->irq = -1;
    170   1.1       igy 
    171   1.1       igy 	pcic_attach(sc);
    172   1.1       igy 	pcic_attach_sockets(sc);
    173   1.1       igy         pcic_attach_sockets_finish(sc);
    174   1.1       igy }
    175   1.1       igy 
    176   1.1       igy static void *
    177   1.1       igy pcic_vrip_chip_intr_establish(pcmcia_chipset_handle_t pch,
    178   1.1       igy 			      struct pcmcia_function *pf,
    179   1.1       igy 			      int ipl,
    180   1.1       igy 			      int (*ih_fun)(void *),
    181   1.1       igy 			      void *ih_arg)
    182   1.1       igy {
    183   1.1       igy 	struct pcic_handle	*h;
    184   1.1       igy 	struct pcic_softc	*sc;
    185   1.1       igy 	struct pcic_vrip_softc	*vsc;
    186   1.1       igy 	struct intrhand		*ih;
    187   1.1       igy 
    188   1.1       igy 	int	irq;
    189   1.1       igy 	int	r;
    190   1.1       igy 
    191   1.1       igy 
    192   1.1       igy 	/*
    193   1.1       igy 	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    194   1.1       igy 	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    195   1.1       igy 	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    196   1.1       igy 	 */
    197   1.1       igy 	irq = 11;
    198   1.1       igy 	/*
    199   1.1       igy 	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    200   1.1       igy 	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    201   1.1       igy 	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    202   1.1       igy 	 */
    203   1.1       igy 
    204   1.1       igy 
    205   1.1       igy 	h = (struct pcic_handle *) pch;
    206   1.9   tsutsui 	vsc = device_private(h->ph_parent);
    207   1.9   tsutsui 	sc = &vsc->sc_pcic;
    208   1.1       igy 
    209   1.1       igy 
    210   1.1       igy 	ih = &vsc->sc_intrhand[irq];
    211   1.1       igy 	if (ih->ih_fun) /* cannot share ecu interrupt */
    212   1.1       igy 		return NULL;
    213   1.1       igy 	ih->ih_fun = ih_fun;
    214   1.1       igy 	ih->ih_arg = ih_arg;
    215   1.1       igy 
    216   1.1       igy 	h->ih_irq = irq;
    217   1.1       igy 	if (h->flags & PCIC_FLAG_ENABLED) {
    218   1.1       igy 		r = pcic_read(h, PCIC_INTR);
    219   1.3   mycroft 		r &= ~PCIC_INTR_IRQ_MASK;
    220   1.3   mycroft 		pcic_write(h, PCIC_INTR, r | irq);
    221   1.1       igy         }
    222   1.1       igy 
    223   1.1       igy 	vsc->sc_intr_mask &= ~(1 << irq);
    224   1.1       igy 	bus_space_write_2(sc->iot, sc->ioh, ECU_INTMSK_REG_W,
    225   1.1       igy 			  vsc->sc_intr_mask);
    226   1.1       igy 
    227   1.1       igy 	return ih;
    228   1.1       igy }
    229   1.1       igy 
    230   1.1       igy static void
    231   1.1       igy pcic_vrip_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *arg)
    232   1.1       igy {
    233   1.1       igy 	struct pcic_handle	*h;
    234   1.1       igy 	struct pcic_softc	*sc;
    235   1.1       igy 	struct pcic_vrip_softc	*vsc;
    236   1.1       igy 	struct intrhand		*ih = arg;
    237   1.1       igy 
    238   1.1       igy 	int	s;
    239   1.1       igy 	int	r;
    240   1.1       igy 
    241   1.1       igy 	h = (struct pcic_handle *) pch;
    242   1.9   tsutsui 	vsc = device_private(h->ph_parent);
    243   1.9   tsutsui 	sc = &vsc->sc_pcic;
    244   1.1       igy 
    245   1.1       igy 	if (ih != &vsc->sc_intrhand[h->ih_irq])
    246   1.1       igy 		panic("pcic_vrip_chip_intr_disestablish: bad handler");
    247   1.1       igy 
    248   1.1       igy 	s = splhigh();
    249   1.1       igy 
    250   1.1       igy 	vsc->sc_intr_mask |= 1 << h->ih_irq;
    251   1.1       igy 	bus_space_write_2(sc->iot, sc->ioh, ECU_INTMSK_REG_W,
    252   1.1       igy 			  vsc->sc_intr_mask);
    253   1.1       igy 
    254   1.1       igy 	h->ih_irq = 0;
    255   1.1       igy 	if (h->flags & PCIC_FLAG_ENABLED) {
    256   1.1       igy 		r = pcic_read(h, PCIC_INTR);
    257   1.1       igy 		r &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
    258   1.1       igy 		pcic_write(h, PCIC_INTR, r);
    259   1.1       igy         }
    260   1.1       igy 
    261   1.1       igy 	ih->ih_fun = NULL;
    262   1.1       igy 	ih->ih_arg = NULL;
    263   1.1       igy 
    264   1.1       igy 	splx(s);
    265   1.1       igy }
    266   1.1       igy 
    267   1.1       igy /*
    268   1.1       igy  * interrupt handler
    269   1.1       igy  */
    270   1.1       igy static int
    271   1.1       igy pcic_vrip_intr(void *arg)
    272   1.1       igy {
    273   1.1       igy 	struct pcic_vrip_softc	*vsc = arg;
    274   1.9   tsutsui 	struct pcic_softc	*sc = &vsc->sc_pcic;
    275   1.1       igy 	int			i;
    276   1.8   tsutsui 	uint16_t		r;
    277   1.1       igy 
    278   1.1       igy 	r = bus_space_read_2(sc->iot, sc->ioh, ECU_INTSTAT_REG_W)
    279   1.1       igy 		& ~vsc->sc_intr_mask;
    280   1.1       igy 
    281   1.1       igy 	for (i = 0; i < ECU_MAX_INTR; i++) {
    282   1.1       igy 		struct intrhand	*ih = &vsc->sc_intrhand[i];
    283   1.1       igy 		if (ih->ih_fun && (r & (1 << i)))
    284   1.1       igy 			ih->ih_fun(ih->ih_arg);
    285   1.1       igy 	}
    286   1.1       igy 	return 1;
    287   1.1       igy }
    288