Home | History | Annotate | Line # | Download | only in ioc
oioc.c revision 1.1.6.2
      1  1.1.6.2  jym /*	$NetBSD: oioc.c,v 1.1.6.2 2009/05/13 17:18:19 jym Exp $	*/
      2  1.1.6.2  jym 
      3  1.1.6.2  jym /*
      4  1.1.6.2  jym  * Copyright (c) 2009 Stephen M. Rumble
      5  1.1.6.2  jym  * All rights reserved.
      6  1.1.6.2  jym  *
      7  1.1.6.2  jym  * Redistribution and use in source and binary forms, with or without
      8  1.1.6.2  jym  * modification, are permitted provided that the following conditions
      9  1.1.6.2  jym  * are met:
     10  1.1.6.2  jym  * 1. Redistributions of source code must retain the above copyright
     11  1.1.6.2  jym  *    notice, this list of conditions and the following disclaimer.
     12  1.1.6.2  jym  * 2. The name of the author may not be used to endorse or promote products
     13  1.1.6.2  jym  *    derived from this software without specific prior written permission.
     14  1.1.6.2  jym  *
     15  1.1.6.2  jym  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1.6.2  jym  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  1.1.6.2  jym  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  1.1.6.2  jym  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  1.1.6.2  jym  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  1.1.6.2  jym  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  1.1.6.2  jym  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  1.1.6.2  jym  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  1.1.6.2  jym  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  1.1.6.2  jym  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  1.1.6.2  jym  */
     26  1.1.6.2  jym 
     27  1.1.6.2  jym /*
     28  1.1.6.2  jym  * IOC1/IOC2 chips on IP4 and IP6/IP10 machines. This interfaces the SCSI
     29  1.1.6.2  jym  * and Ethernet controllers, performs DMA for the former, and does address
     30  1.1.6.2  jym  * space translation for the latter (maps the lance memory space to physical
     31  1.1.6.2  jym  * pages).
     32  1.1.6.2  jym  *
     33  1.1.6.2  jym  * 'I/O Controller' is a sufficiently generic name that SGI created another
     34  1.1.6.2  jym  * one for IP24, which basically stuffed a bunch of miscellany on an ASIC.
     35  1.1.6.2  jym  * So, we'll call ourselves 'Old IOC' and hope that there wasn't an even older
     36  1.1.6.2  jym  * one.
     37  1.1.6.2  jym  */
     38  1.1.6.2  jym 
     39  1.1.6.2  jym #include <sys/cdefs.h>
     40  1.1.6.2  jym __KERNEL_RCSID(0, "$NetBSD: oioc.c,v 1.1.6.2 2009/05/13 17:18:19 jym Exp $");
     41  1.1.6.2  jym 
     42  1.1.6.2  jym #include <sys/param.h>
     43  1.1.6.2  jym #include <sys/device.h>
     44  1.1.6.2  jym 
     45  1.1.6.2  jym #define _SGIMIPS_BUS_DMA_PRIVATE
     46  1.1.6.2  jym #include <machine/cpu.h>
     47  1.1.6.2  jym #include <machine/locore.h>
     48  1.1.6.2  jym #include <machine/autoconf.h>
     49  1.1.6.2  jym #include <machine/bus.h>
     50  1.1.6.2  jym #include <machine/machtype.h>
     51  1.1.6.2  jym #include <machine/sysconf.h>
     52  1.1.6.2  jym 
     53  1.1.6.2  jym #include <sgimips/ioc/oiocreg.h>
     54  1.1.6.2  jym #include <sgimips/ioc/oiocvar.h>
     55  1.1.6.2  jym 
     56  1.1.6.2  jym #include "locators.h"
     57  1.1.6.2  jym 
     58  1.1.6.2  jym struct oioc_softc {
     59  1.1.6.2  jym 	struct device   	sc_dev;
     60  1.1.6.2  jym 
     61  1.1.6.2  jym 	int			sc_burst_dma;
     62  1.1.6.2  jym 
     63  1.1.6.2  jym 	bus_space_tag_t		sc_iot;
     64  1.1.6.2  jym 	bus_space_handle_t	sc_ioh;
     65  1.1.6.2  jym };
     66  1.1.6.2  jym 
     67  1.1.6.2  jym static int      oioc_match(struct device *, struct cfdata *, void *);
     68  1.1.6.2  jym static void     oioc_attach(struct device *, struct device *, void *);
     69  1.1.6.2  jym static int	oioc_print(void *, const char *);
     70  1.1.6.2  jym 
     71  1.1.6.2  jym CFATTACH_DECL(oioc, sizeof(struct oioc_softc),
     72  1.1.6.2  jym     oioc_match, oioc_attach, NULL, NULL);
     73  1.1.6.2  jym 
     74  1.1.6.2  jym struct oioc_device {
     75  1.1.6.2  jym 	const char *od_name;
     76  1.1.6.2  jym 	int         od_irq;
     77  1.1.6.2  jym } oioc_devices[] = {
     78  1.1.6.2  jym 	{ "oiocsc", 4 },
     79  1.1.6.2  jym 	{ "le",     5 },
     80  1.1.6.2  jym 	{ NULL,   0 }
     81  1.1.6.2  jym };
     82  1.1.6.2  jym 
     83  1.1.6.2  jym static int
     84  1.1.6.2  jym oioc_match(struct device * parent, struct cfdata * match, void *aux)
     85  1.1.6.2  jym {
     86  1.1.6.2  jym 
     87  1.1.6.2  jym 	switch(mach_type) {
     88  1.1.6.2  jym 	case MACH_SGI_IP4:
     89  1.1.6.2  jym 	case MACH_SGI_IP6 | MACH_SGI_IP10:
     90  1.1.6.2  jym 		return (1);
     91  1.1.6.2  jym 	}
     92  1.1.6.2  jym 
     93  1.1.6.2  jym 	return (0);
     94  1.1.6.2  jym }
     95  1.1.6.2  jym 
     96  1.1.6.2  jym static void
     97  1.1.6.2  jym oioc_attach(struct device * parent, struct device * self, void *aux)
     98  1.1.6.2  jym {
     99  1.1.6.2  jym 	struct oioc_softc *sc = (struct oioc_softc *)self;
    100  1.1.6.2  jym 	struct mainbus_attach_args *ma = aux;
    101  1.1.6.2  jym 	uint32_t reg1, reg2;
    102  1.1.6.2  jym 	int oiocrev, i;
    103  1.1.6.2  jym 
    104  1.1.6.2  jym 	sc->sc_iot = SGIMIPS_BUS_SPACE_NORMAL;
    105  1.1.6.2  jym 	if (bus_space_map(sc->sc_iot, ma->ma_addr, 0,
    106  1.1.6.2  jym 	    BUS_SPACE_MAP_LINEAR, &sc->sc_ioh))
    107  1.1.6.2  jym 		panic("oioc_attach: could not allocate memory\n");
    108  1.1.6.2  jym 
    109  1.1.6.2  jym 	if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ma->ma_addr +
    110  1.1.6.2  jym 	    OIOC2_CONFIG), 4))
    111  1.1.6.2  jym 		oiocrev = 1;
    112  1.1.6.2  jym 	else
    113  1.1.6.2  jym 		oiocrev = 2;
    114  1.1.6.2  jym 
    115  1.1.6.2  jym 	printf("\noioc0: Old SGI IOC%d\n", oiocrev);
    116  1.1.6.2  jym 
    117  1.1.6.2  jym 	if (oiocrev == 2) {
    118  1.1.6.2  jym 		char buf[64];
    119  1.1.6.2  jym 
    120  1.1.6.2  jym 		/* Try to enable burst mode. If we can't, we can't... */
    121  1.1.6.2  jym 		reg1  = 12 << OIOC2_CONFIG_HIWAT_SHFT;
    122  1.1.6.2  jym 		reg1 |= OIOC2_CONFIG_BURST_MASK;
    123  1.1.6.2  jym 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, OIOC2_CONFIG, reg1);
    124  1.1.6.2  jym 		DELAY(1000);
    125  1.1.6.2  jym 		reg2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, OIOC2_CONFIG);
    126  1.1.6.2  jym 		if ((reg2 & (reg1 | OIOC2_CONFIG_NOSYNC_MASK)) == reg1)
    127  1.1.6.2  jym 			sc->sc_burst_dma = 1;
    128  1.1.6.2  jym 
    129  1.1.6.2  jym 		snprintb(buf, sizeof(buf),
    130  1.1.6.2  jym 		    "\177\020"
    131  1.1.6.2  jym 		    "f\0\4HIWAT\0"
    132  1.1.6.2  jym 		    "f\4\2ID\0"
    133  1.1.6.2  jym 		    "b\6NOSYNC\0"
    134  1.1.6.2  jym 		    "b\7BURST\0"
    135  1.1.6.2  jym 		    "f\x8\7COUNT\0"
    136  1.1.6.2  jym 		    "f\x10\6SCP\0"
    137  1.1.6.2  jym 		    "f\x1c\4IOP\0\0",
    138  1.1.6.2  jym 		    (u_quad_t)reg2 & 0xffffffff);
    139  1.1.6.2  jym 		printf("oioc0: %s\n", buf);
    140  1.1.6.2  jym 	}
    141  1.1.6.2  jym 
    142  1.1.6.2  jym 	printf("oioc0: Burst DMA %ssupported\n",
    143  1.1.6.2  jym 	    (sc->sc_burst_dma) ? "" : "not ");
    144  1.1.6.2  jym 
    145  1.1.6.2  jym 	for (i = 0; oioc_devices[i].od_name != NULL; i++) {
    146  1.1.6.2  jym 		struct oioc_attach_args oa;
    147  1.1.6.2  jym 
    148  1.1.6.2  jym 		oa.oa_name      = oioc_devices[i].od_name;
    149  1.1.6.2  jym 		oa.oa_irq       = oioc_devices[i].od_irq;
    150  1.1.6.2  jym 		oa.oa_burst_dma = sc->sc_burst_dma;
    151  1.1.6.2  jym 		oa.oa_st        = SGIMIPS_BUS_SPACE_NORMAL;
    152  1.1.6.2  jym 		oa.oa_sh        = sc->sc_ioh;
    153  1.1.6.2  jym 		oa.oa_dmat      = &sgimips_default_bus_dma_tag;
    154  1.1.6.2  jym 		config_found_ia(self, "oioc", &oa, oioc_print);
    155  1.1.6.2  jym 	}
    156  1.1.6.2  jym }
    157  1.1.6.2  jym 
    158  1.1.6.2  jym static int
    159  1.1.6.2  jym oioc_print(void *aux, const char *pnp)
    160  1.1.6.2  jym {
    161  1.1.6.2  jym 	struct oioc_attach_args *oa = aux;
    162  1.1.6.2  jym 
    163  1.1.6.2  jym 	if (pnp)
    164  1.1.6.2  jym 		printf("%s at %s", oa->oa_name, pnp);
    165  1.1.6.2  jym 
    166  1.1.6.2  jym 	return (UNCONF);
    167  1.1.6.2  jym }
    168