xref: /netbsd-src/sys/arch/x68k/dev/xel.c (revision cd22f25e6f6d1cc1f197fe8c5468a80f51d1c4e1)
1 /*	$NetBSD: xel.c,v 1.14 2008/04/28 20:23:39 martin Exp $	*/
2 
3 /*
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Minoura Makoto.
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  * TSR Xellent30 driver.
34  * Detect Xellent30, and reserve its I/O area.
35  */
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: xel.c,v 1.14 2008/04/28 20:23:39 martin Exp $");
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/device.h>
44 
45 #include <machine/cpu.h>
46 #include <machine/bus.h>
47 
48 #include <arch/x68k/dev/intiovar.h>
49 
50 static paddr_t xel_addr(struct device *, struct cfdata *,
51 	struct intio_attach_args *);
52 static int xel_probe(paddr_t);
53 static int xel_match(struct device *, struct cfdata *, void *);
54 static void xel_attach(struct device *, struct device *, void *);
55 
56 struct xel_softc {
57 	struct device dev;
58 
59 	bus_space_tag_t sc_bst;
60 	bus_space_handle_t sc_bh;
61 };
62 
63 CFATTACH_DECL(xel, sizeof(struct xel_softc),
64     xel_match, xel_attach, NULL, NULL);
65 
66 static paddr_t xel_addrs[] = { 0xec0000, 0xec4000, 0xec8000, 0xecc000 };
67 
68 #define XEL_MODE_RAM_LOWER	0x00
69 #define XEL_MODE_RAM_HIGHER	0x01
70 #define XEL_MODE_UNMAP_RAM	0x00
71 #define XEL_MODE_MAP_RAM	0x02
72 #define XEL_MODE_MPU_000	0x00
73 #define XEL_MODE_MPU_030	0x04
74 
75 #define XEL_RAM_ADDR_LOWER	0xbc0000
76 #define XEL_RAM_ADDR_HIGHER	0xfc0000
77 
78 
79 static paddr_t
80 xel_addr(struct device *parent, struct cfdata *match,
81     struct intio_attach_args *ia)
82 {
83 	paddr_t addr = 0;
84 
85 	if (match->cf_addr == INTIOCF_ADDR_DEFAULT) {
86 		int i;
87 
88 		for (i = 0; i < sizeof(xel_addrs)/sizeof(xel_addrs[0]); i++) {
89 			if (xel_probe(xel_addrs[i])) {
90 				addr = xel_addrs[i];
91 				break;
92 			}
93 		}
94 	} else {
95 		if (xel_probe((paddr_t) match->cf_addr))
96 			addr = (paddr_t) match->cf_addr;
97 	}
98 
99 	if (addr) {
100 		/* found! */
101 		ia->ia_addr = (int) addr;
102 		ia->ia_size = 0x4000;
103 		if (intio_map_allocate_region(parent, ia, INTIO_MAP_TESTONLY)
104 		    < 0)
105 			return 0;
106 		else
107 			return addr;
108 	}
109 
110 	return 0;
111 }
112 
113 extern int *nofault;
114 
115 static int
116 xel_probe(paddr_t addr)
117 {
118 	u_int32_t b1, b2;
119 	volatile u_int16_t *start = (volatile void *)INTIO_ADDR(addr);
120 	label_t	faultbuf;
121 	volatile u_int32_t *sram = (volatile void *)INTIO_ADDR(XEL_RAM_ADDR_HIGHER);
122 
123 	if (badaddr(start))
124 		return 0;
125 
126 	nofault = (int *) &faultbuf;
127 	if (setjmp(&faultbuf)) {
128 		nofault = NULL;
129 		return 0;
130 	}
131 
132 	b1 = sram[0];
133 	b2 = sram[1];
134 	/* Try to map the Xellent local memory. */
135 	start[0] = XEL_MODE_RAM_HIGHER | XEL_MODE_MAP_RAM | XEL_MODE_MPU_030;
136 
137 #if 0
138 	/* the contents should be deferent. */
139 	if (b1 == sram[0] && b2 == sram[1]) {
140 		nofault = (int *) 0;
141 		return 0;
142 	}
143 #else
144 	/* Try to write to the local memory. */
145 	sram[0] = 0x55555555;
146 	sram[1] = 0xaaaaaaaa;
147 	if (sram[0] != 0x55555555 || sram[1] != 0xaaaaaaaa) {
148 		sram[0] = b1;
149 		sram[1] = b2;
150 		nofault = (int *) 0;
151 		return 0;
152 	}
153 	sram[0] = 0xaaaaaaaa;
154 	sram[1] = 0x55555555;
155 	if (sram[0] != 0xaaaaaaaa || sram[1] != 0x55555555) {
156 		sram[0] = b1;
157 		sram[1] = b2;
158 		nofault = (int *) 0;
159 		return 0;
160 	}
161 	sram[0] = b1;
162 	sram[1] = b2;
163 #endif
164 
165 	/* Unmap. */
166 	start[0] = XEL_MODE_UNMAP_RAM | XEL_MODE_MPU_030;
167 
168 	nofault = NULL;
169 	return 1;
170 }
171 
172 static int
173 xel_match(struct device *parent, struct cfdata *match, void *aux)
174 {
175 	struct intio_attach_args *ia = aux;
176 
177 	if (strcmp(ia->ia_name, "xel") != 0)
178 		return 0;
179 
180 	if (xel_addr(parent, match, ia)) {
181 #ifdef DIAGNOSTIC
182 		if (cputype != CPU_68030)
183 			panic("Non-030 Xellent???");
184 #endif
185 		return 1;
186 	}
187 	return 0;
188 }
189 
190 static void
191 xel_attach(struct device *parent, struct device *self, void *aux)
192 {
193 	struct xel_softc *sc = (void *)self;
194 	struct intio_attach_args *ia = aux;
195 	struct cfdata *cf = device_cfdata(self);
196 	paddr_t addr;
197 	int r;
198 
199 	addr = xel_addr(parent, cf, aux);
200 	sc->sc_bst = ia->ia_bst;
201 	ia->ia_addr = (int) addr;
202 	ia->ia_size = 0x4000;
203 	r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE);
204 #ifdef DIAGNOSTIC
205 	if (r)
206 		panic("IO map for Xellent30 corruption??");
207 #endif
208 	printf(": Xellent30 MPU Accelerator.\n");
209 
210 	return;
211 }
212