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