xref: /netbsd-src/sys/arch/mvme68k/dev/mainbus.c (revision a542b07802ade0397725fd0b67be83b8b79eb446)
1*a542b078Sthorpej /*	$NetBSD: mainbus.c,v 1.24 2024/01/18 05:12:29 thorpej Exp $	*/
29c745dbdSscw 
39c745dbdSscw /*-
49c745dbdSscw  * Copyright (c) 2000 The NetBSD Foundation, Inc.
59c745dbdSscw  * All rights reserved.
69c745dbdSscw  *
79c745dbdSscw  * This code is derived from software contributed to The NetBSD Foundation
89c745dbdSscw  * by Steve C. Woodford
99c745dbdSscw  *
109c745dbdSscw  * Redistribution and use in source and binary forms, with or without
119c745dbdSscw  * modification, are permitted provided that the following conditions
129c745dbdSscw  * are met:
139c745dbdSscw  * 1. Redistributions of source code must retain the above copyright
149c745dbdSscw  *    notice, this list of conditions and the following disclaimer.
159c745dbdSscw  * 2. Redistributions in binary form must reproduce the above copyright
169c745dbdSscw  *    notice, this list of conditions and the following disclaimer in the
179c745dbdSscw  *    documentation and/or other materials provided with the distribution.
189c745dbdSscw  *
199c745dbdSscw  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209c745dbdSscw  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219c745dbdSscw  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229c745dbdSscw  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239c745dbdSscw  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249c745dbdSscw  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259c745dbdSscw  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269c745dbdSscw  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279c745dbdSscw  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289c745dbdSscw  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299c745dbdSscw  * POSSIBILITY OF SUCH DAMAGE.
309c745dbdSscw  */
319c745dbdSscw 
329c745dbdSscw /*
339c745dbdSscw  * Derived from the mainbus code in mvme68k/autoconf.c by Chuck Cranor.
349c745dbdSscw  */
359c745dbdSscw 
364b2744bfSlukem #include <sys/cdefs.h>
37*a542b078Sthorpej __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.24 2024/01/18 05:12:29 thorpej Exp $");
384b2744bfSlukem 
39*a542b078Sthorpej #include "opt_mvmeconf.h"
4035110949Sscw #include "vmetwo.h"
4135110949Sscw 
429c745dbdSscw #include <sys/param.h>
439c745dbdSscw #include <sys/kernel.h>
449c745dbdSscw #include <sys/systm.h>
459c745dbdSscw #include <sys/device.h>
469c745dbdSscw 
479c745dbdSscw #define _MVME68K_BUS_DMA_PRIVATE
487d191ffeSscw #define _MVME68K_BUS_SPACE_PRIVATE
499c745dbdSscw #include <machine/bus.h>
509c745dbdSscw #undef _MVME68K_BUS_DMA_PRIVATE
517d191ffeSscw #undef _MVME68K_BUS_SPACE_PRIVATE
529c745dbdSscw #include <machine/cpu.h>
539c745dbdSscw 
549c745dbdSscw #include <mvme68k/dev/mainbus.h>
559c745dbdSscw 
5635110949Sscw #if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
5735110949Sscw #if NVMETWO == 0
5835110949Sscw #include <dev/vme/vmevar.h>
59b303a941Sscw #include <dev/mvme/mvmebus.h>
60b303a941Sscw #include <dev/mvme/vme_twovar.h>
6135110949Sscw #endif
6235110949Sscw #endif
6353323bf3Sscw 
64612b7ee5Smatt void mainbus_attach(device_t, device_t, void *);
65612b7ee5Smatt int mainbus_match(device_t, cfdata_t, void *);
66a07f7c80Stsutsui int mainbus_print(void *, const char *);
679c745dbdSscw 
68612b7ee5Smatt CFATTACH_DECL_NEW(mainbus, 0,
69c5e91d44Sthorpej     mainbus_match, mainbus_attach, NULL, NULL);
709c745dbdSscw 
719c745dbdSscw 
729c745dbdSscw struct mainbus_devices {
739c745dbdSscw 	const char *md_name;
749c745dbdSscw 	bus_addr_t md_offset;
759c745dbdSscw };
769c745dbdSscw 
779c745dbdSscw #ifdef MVME147
789c745dbdSscw static struct mainbus_devices mainbusdevs_147[] = {
799c745dbdSscw 	{"pcc", MAINBUS_PCC_OFFSET},
80bb210bdaSscw 	{"timekeeper", MAINBUS_TK147_OFFSET},
819c745dbdSscw 	{NULL, 0}
829c745dbdSscw };
839c745dbdSscw #endif
849c745dbdSscw 
85b6f0a678Sscw #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
869c745dbdSscw static struct mainbus_devices mainbusdevs_1x7[] = {
879c745dbdSscw 	{"pcctwo", MAINBUS_PCCTWO_OFFSET},
889c745dbdSscw 	{"vmetwo", MAINBUS_VMETWO_OFFSET},
89bb210bdaSscw 	{"timekeeper", MAINBUS_TIMEKEEPER_OFFSET},
909c745dbdSscw 	{NULL, 0}
919c745dbdSscw };
929c745dbdSscw #endif
939c745dbdSscw 
947d191ffeSscw struct mvme68k_bus_dma_tag _mainbus_dma_tag = {
957d191ffeSscw 	NULL,
967d191ffeSscw 	_bus_dmamap_create,
977d191ffeSscw 	_bus_dmamap_destroy,
987d191ffeSscw 	_bus_dmamap_load_direct,
997d191ffeSscw 	_bus_dmamap_load_mbuf_direct,
1007d191ffeSscw 	_bus_dmamap_load_uio_direct,
1017d191ffeSscw 	_bus_dmamap_load_raw_direct,
1027d191ffeSscw 	_bus_dmamap_unload,
1037d191ffeSscw 	NULL,			/* Set up at run-time */
1047d191ffeSscw 	_bus_dmamem_alloc,
1057d191ffeSscw 	_bus_dmamem_free,
1067d191ffeSscw 	_bus_dmamem_map,
1077d191ffeSscw 	_bus_dmamem_unmap,
1087d191ffeSscw 	_bus_dmamem_mmap
1097d191ffeSscw };
1107d191ffeSscw 
1117d191ffeSscw struct mvme68k_bus_space_tag _mainbus_space_tag = {
1127d191ffeSscw 	NULL,
1137d191ffeSscw 	_bus_space_map,
1147d191ffeSscw 	_bus_space_unmap,
1157d191ffeSscw 	_bus_space_peek_1,
1167d191ffeSscw 	_bus_space_peek_2,
1177d191ffeSscw 	_bus_space_peek_4,
1187d191ffeSscw 	_bus_space_poke_1,
1197d191ffeSscw 	_bus_space_poke_2,
1207d191ffeSscw 	_bus_space_poke_4
1217d191ffeSscw };
1227d191ffeSscw 
1237d191ffeSscw 
1249c745dbdSscw /* ARGSUSED */
1259c745dbdSscw int
mainbus_match(device_t parent,cfdata_t cf,void * args)126612b7ee5Smatt mainbus_match(device_t parent, cfdata_t cf, void *args)
1279c745dbdSscw {
1289c745dbdSscw 	static int mainbus_matched;
1299c745dbdSscw 
1309c745dbdSscw 	if (mainbus_matched)
131a07f7c80Stsutsui 		return 0;
1329c745dbdSscw 
133a07f7c80Stsutsui 	return (mainbus_matched = 1);
1349c745dbdSscw }
1359c745dbdSscw 
1369c745dbdSscw /* ARGSUSED */
1379c745dbdSscw void
mainbus_attach(device_t parent,device_t self,void * args)138612b7ee5Smatt mainbus_attach(device_t parent, device_t self, void *args)
1399c745dbdSscw {
1409c745dbdSscw 	struct mainbus_attach_args ma;
1419c745dbdSscw 	struct mainbus_devices *devices;
1429c745dbdSscw 	int i;
1439c745dbdSscw 
1449c745dbdSscw 	printf("\n");
1459c745dbdSscw 
1469c745dbdSscw 	/*
1479c745dbdSscw 	 * Attach children appropriate for this CPU.
1489c745dbdSscw 	 */
1499c745dbdSscw 	switch (machineid) {
1509c745dbdSscw #ifdef MVME147
1519c745dbdSscw 	case MVME_147:
1529c745dbdSscw 		devices = mainbusdevs_147;
1537d191ffeSscw 		_mainbus_dma_tag._dmamap_sync = _bus_dmamap_sync_030;
1549c745dbdSscw 		break;
1559c745dbdSscw #endif
1569c745dbdSscw 
157b6f0a678Sscw #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
1589c745dbdSscw 	case MVME_162:
1599c745dbdSscw 	case MVME_167:
160b6f0a678Sscw 	case MVME_172:
1619c745dbdSscw 	case MVME_177:
1629c745dbdSscw 		devices = mainbusdevs_1x7;
1637d191ffeSscw 		_mainbus_dma_tag._dmamap_sync = _bus_dmamap_sync_0460;
1649c745dbdSscw 		break;
1659c745dbdSscw #endif
1669c745dbdSscw 
1679c745dbdSscw 	default:
1689c745dbdSscw 		panic("mainbus_attach: impossible CPU type");
1699c745dbdSscw 	}
1709c745dbdSscw 
1719c745dbdSscw 	for (i = 0; devices[i].md_name != NULL; ++i) {
17259ba4788Sscw 		/*
17335110949Sscw 		 * On mvme162 and up, if the kernel config file had no vmetwo0
17435110949Sscw 		 * device, we have to do some manual initialisation on the
17535110949Sscw 		 * VMEChip2 to get local interrupts working (ABORT switch,
17635110949Sscw 		 * hardware assisted soft interrupts).
17735110949Sscw 		 */
17835110949Sscw #if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
17935110949Sscw #if NVMETWO == 0
1807e69c325Sscw 		if (devices[i].md_offset == MAINBUS_VMETWO_OFFSET
18135110949Sscw #if defined(MVME147)
1827e69c325Sscw 		    && machineid != MVME_147
18335110949Sscw #endif
1847e69c325Sscw 		    ) {
18535110949Sscw 			(void)vmetwo_probe(&_mainbus_space_tag,
18635110949Sscw 			    intiobase_phys + MAINBUS_VMETWO_OFFSET);
1877e69c325Sscw 			continue;
18835110949Sscw 		}
18935110949Sscw #endif
19035110949Sscw #endif
1917e69c325Sscw 		ma.ma_name = devices[i].md_name;
1927e69c325Sscw 		ma.ma_dmat = &_mainbus_dma_tag;
1937e69c325Sscw 		ma.ma_bust = &_mainbus_space_tag;
1947e69c325Sscw 		ma.ma_offset = devices[i].md_offset + intiobase_phys;
1957e69c325Sscw 
196c7fb772bSthorpej 		(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
1977e69c325Sscw 	}
1987e69c325Sscw 
19935110949Sscw 
20035110949Sscw 	/*
2017e2f2acbSscw 	 * Attach the memory controllers on mvme162->mvme177.
2027e2f2acbSscw 	 * Note: These *must* be attached after the PCCChip2/MCChip.
2037e2f2acbSscw 	 * They must also be attached *after* the VMEchip2 has been
2047e2f2acbSscw 	 * initialised (either by the driver, or the vmetwo_probe()
2057e2f2acbSscw 	 * call above).
2067e2f2acbSscw 	 */
2077e2f2acbSscw #if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
2087e2f2acbSscw #if defined(MVME147)
2097e2f2acbSscw 	if (machineid != MVME_147)
2107e2f2acbSscw #endif
2117e2f2acbSscw 	{
2127e2f2acbSscw 		ma.ma_name = "memc";
2137e2f2acbSscw 		ma.ma_dmat = &_mainbus_dma_tag;
2147e2f2acbSscw 		ma.ma_bust = &_mainbus_space_tag;
2157e2f2acbSscw 		ma.ma_offset = MAINBUS_MEMC1_OFFSET + intiobase_phys;
216c7fb772bSthorpej 		(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
2177e2f2acbSscw 		ma.ma_offset = MAINBUS_MEMC2_OFFSET + intiobase_phys;
218c7fb772bSthorpej 		(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
2197e2f2acbSscw 	}
2207e2f2acbSscw #endif
2217e2f2acbSscw 
2227e2f2acbSscw 	/*
22359ba4788Sscw 	 * Attach Industry Pack modules on mvme162 and mvme172
22459ba4788Sscw 	 */
22559ba4788Sscw #if defined(MVME162) || defined(MVME172)
22659ba4788Sscw #if defined(MVME147) || defined(MVME167) || defined(MVME177)
22759ba4788Sscw 	if (machineid == MVME_162 || machineid == MVME_172)
22859ba4788Sscw #endif
22959ba4788Sscw 	{
23059ba4788Sscw 		ma.ma_name = "ipack";
23159ba4788Sscw 		ma.ma_dmat = &_mainbus_dma_tag;
23259ba4788Sscw 		ma.ma_bust = &_mainbus_space_tag;
23359ba4788Sscw 		ma.ma_offset = MAINBUS_IPACK_OFFSET + intiobase_phys;
234c7fb772bSthorpej 		(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
23559ba4788Sscw 	}
23659ba4788Sscw #endif
2379c745dbdSscw }
2389c745dbdSscw 
2399c745dbdSscw int
mainbus_print(void * aux,const char * cp)240a07f7c80Stsutsui mainbus_print(void *aux, const char *cp)
2419c745dbdSscw {
2429c745dbdSscw 	struct mainbus_attach_args *ma;
2439c745dbdSscw 
2449c745dbdSscw 	ma = aux;
2459c745dbdSscw 
2469c745dbdSscw 	if (cp)
247dbb0f0ebSthorpej 		aprint_normal("%s at %s", ma->ma_name, cp);
2489c745dbdSscw 
249dbb0f0ebSthorpej 	aprint_normal(" address 0x%lx", ma->ma_offset);
2509c745dbdSscw 
251a07f7c80Stsutsui 	return UNCONF;
2529c745dbdSscw }
253