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