xref: /netbsd/sys/arch/mvme68k/dev/mainbus.c (revision 6550d01e)
1 /*	$NetBSD: mainbus.c,v 1.20 2008/04/28 20:23:29 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Steve C. Woodford
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  * Derived from the mainbus code in mvme68k/autoconf.c by Chuck Cranor.
34  */
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.20 2008/04/28 20:23:29 martin Exp $");
38 
39 #include "vmetwo.h"
40 
41 #include <sys/param.h>
42 #include <sys/kernel.h>
43 #include <sys/systm.h>
44 #include <sys/device.h>
45 
46 #define _MVME68K_BUS_DMA_PRIVATE
47 #define _MVME68K_BUS_SPACE_PRIVATE
48 #include <machine/bus.h>
49 #undef _MVME68K_BUS_DMA_PRIVATE
50 #undef _MVME68K_BUS_SPACE_PRIVATE
51 #include <machine/cpu.h>
52 
53 #include <mvme68k/dev/mainbus.h>
54 
55 #if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
56 #if NVMETWO == 0
57 #include <dev/vme/vmevar.h>
58 #include <dev/mvme/mvmebus.h>
59 #include <dev/mvme/vme_twovar.h>
60 #endif
61 #endif
62 
63 void mainbus_attach(struct device *, struct device *, void *);
64 int mainbus_match(struct device *, struct cfdata *, void *);
65 int mainbus_print(void *, const char *);
66 
67 CFATTACH_DECL(mainbus, sizeof(struct device),
68     mainbus_match, mainbus_attach, NULL, NULL);
69 
70 
71 struct mainbus_devices {
72 	const char *md_name;
73 	bus_addr_t md_offset;
74 };
75 
76 #ifdef MVME147
77 static struct mainbus_devices mainbusdevs_147[] = {
78 	{"pcc", MAINBUS_PCC_OFFSET},
79 	{"timekeeper", MAINBUS_TK147_OFFSET},
80 	{NULL, 0}
81 };
82 #endif
83 
84 #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
85 static struct mainbus_devices mainbusdevs_1x7[] = {
86 	{"pcctwo", MAINBUS_PCCTWO_OFFSET},
87 	{"vmetwo", MAINBUS_VMETWO_OFFSET},
88 	{"timekeeper", MAINBUS_TIMEKEEPER_OFFSET},
89 	{NULL, 0}
90 };
91 #endif
92 
93 struct mvme68k_bus_dma_tag _mainbus_dma_tag = {
94 	NULL,
95 	_bus_dmamap_create,
96 	_bus_dmamap_destroy,
97 	_bus_dmamap_load_direct,
98 	_bus_dmamap_load_mbuf_direct,
99 	_bus_dmamap_load_uio_direct,
100 	_bus_dmamap_load_raw_direct,
101 	_bus_dmamap_unload,
102 	NULL,			/* Set up at run-time */
103 	_bus_dmamem_alloc,
104 	_bus_dmamem_free,
105 	_bus_dmamem_map,
106 	_bus_dmamem_unmap,
107 	_bus_dmamem_mmap
108 };
109 
110 struct mvme68k_bus_space_tag _mainbus_space_tag = {
111 	NULL,
112 	_bus_space_map,
113 	_bus_space_unmap,
114 	_bus_space_peek_1,
115 	_bus_space_peek_2,
116 	_bus_space_peek_4,
117 	_bus_space_poke_1,
118 	_bus_space_poke_2,
119 	_bus_space_poke_4
120 };
121 
122 
123 /* ARGSUSED */
124 int
125 mainbus_match(struct device *parent, struct cfdata *cf, void *args)
126 {
127 	static int mainbus_matched;
128 
129 	if (mainbus_matched)
130 		return 0;
131 
132 	return (mainbus_matched = 1);
133 }
134 
135 /* ARGSUSED */
136 void
137 mainbus_attach(struct device *parent, struct device *self, void *args)
138 {
139 	struct mainbus_attach_args ma;
140 	struct mainbus_devices *devices;
141 	int i;
142 
143 	printf("\n");
144 
145 	/*
146 	 * Attach children appropriate for this CPU.
147 	 */
148 	switch (machineid) {
149 #ifdef MVME147
150 	case MVME_147:
151 		devices = mainbusdevs_147;
152 		_mainbus_dma_tag._dmamap_sync = _bus_dmamap_sync_030;
153 		break;
154 #endif
155 
156 #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
157 	case MVME_162:
158 	case MVME_167:
159 	case MVME_172:
160 	case MVME_177:
161 		devices = mainbusdevs_1x7;
162 		_mainbus_dma_tag._dmamap_sync = _bus_dmamap_sync_0460;
163 		break;
164 #endif
165 
166 	default:
167 		panic("mainbus_attach: impossible CPU type");
168 	}
169 
170 	for (i = 0; devices[i].md_name != NULL; ++i) {
171 		/*
172 		 * On mvme162 and up, if the kernel config file had no vmetwo0
173 		 * device, we have to do some manual initialisation on the
174 		 * VMEChip2 to get local interrupts working (ABORT switch,
175 		 * hardware assisted soft interrupts).
176 		 */
177 #if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
178 #if NVMETWO == 0
179 		if (devices[i].md_offset == MAINBUS_VMETWO_OFFSET
180 #if defined(MVME147)
181 		    && machineid != MVME_147
182 #endif
183 		    ) {
184 			(void)vmetwo_probe(&_mainbus_space_tag,
185 			    intiobase_phys + MAINBUS_VMETWO_OFFSET);
186 			continue;
187 		}
188 #endif
189 #endif
190 		ma.ma_name = devices[i].md_name;
191 		ma.ma_dmat = &_mainbus_dma_tag;
192 		ma.ma_bust = &_mainbus_space_tag;
193 		ma.ma_offset = devices[i].md_offset + intiobase_phys;
194 
195 		(void)config_found(self, &ma, mainbus_print);
196 	}
197 
198 
199 	/*
200 	 * Attach the memory controllers on mvme162->mvme177.
201 	 * Note: These *must* be attached after the PCCChip2/MCChip.
202 	 * They must also be attached *after* the VMEchip2 has been
203 	 * initialised (either by the driver, or the vmetwo_probe()
204 	 * call above).
205 	 */
206 #if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
207 #if defined(MVME147)
208 	if (machineid != MVME_147)
209 #endif
210 	{
211 		ma.ma_name = "memc";
212 		ma.ma_dmat = &_mainbus_dma_tag;
213 		ma.ma_bust = &_mainbus_space_tag;
214 		ma.ma_offset = MAINBUS_MEMC1_OFFSET + intiobase_phys;
215 		(void)config_found(self, &ma, mainbus_print);
216 		ma.ma_offset = MAINBUS_MEMC2_OFFSET + intiobase_phys;
217 		(void)config_found(self, &ma, mainbus_print);
218 	}
219 #endif
220 
221 	/*
222 	 * Attach Industry Pack modules on mvme162 and mvme172
223 	 */
224 #if defined(MVME162) || defined(MVME172)
225 #if defined(MVME147) || defined(MVME167) || defined(MVME177)
226 	if (machineid == MVME_162 || machineid == MVME_172)
227 #endif
228 	{
229 		ma.ma_name = "ipack";
230 		ma.ma_dmat = &_mainbus_dma_tag;
231 		ma.ma_bust = &_mainbus_space_tag;
232 		ma.ma_offset = MAINBUS_IPACK_OFFSET + intiobase_phys;
233 		(void)config_found(self, &ma, mainbus_print);
234 	}
235 #endif
236 }
237 
238 int
239 mainbus_print(void *aux, const char *cp)
240 {
241 	struct mainbus_attach_args *ma;
242 
243 	ma = aux;
244 
245 	if (cp)
246 		aprint_normal("%s at %s", ma->ma_name, cp);
247 
248 	aprint_normal(" address 0x%lx", ma->ma_offset);
249 
250 	return UNCONF;
251 }
252