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