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