1*8ff6f65dSthorpej /* $NetBSD: gapspci.c,v 1.22 2023/12/20 06:36:03 thorpej Exp $ */
226cf6921Sthorpej
326cf6921Sthorpej /*-
426cf6921Sthorpej * Copyright (c) 2001 Marcus Comstedt
526cf6921Sthorpej * All rights reserved.
626cf6921Sthorpej *
726cf6921Sthorpej * Redistribution and use in source and binary forms, with or without
826cf6921Sthorpej * modification, are permitted provided that the following conditions
926cf6921Sthorpej * are met:
1026cf6921Sthorpej * 1. Redistributions of source code must retain the above copyright
1126cf6921Sthorpej * notice, this list of conditions and the following disclaimer.
1226cf6921Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
1326cf6921Sthorpej * notice, this list of conditions and the following disclaimer in the
1426cf6921Sthorpej * documentation and/or other materials provided with the distribution.
1526cf6921Sthorpej * 3. All advertising materials mentioning features or use of this software
1626cf6921Sthorpej * must display the following acknowledgement:
1726cf6921Sthorpej * This product includes software developed by Marcus Comstedt.
1826cf6921Sthorpej * 4. Neither the name of The NetBSD Foundation nor the names of its
1926cf6921Sthorpej * contributors may be used to endorse or promote products derived
2026cf6921Sthorpej * from this software without specific prior written permission.
2126cf6921Sthorpej *
2226cf6921Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2326cf6921Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2426cf6921Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2526cf6921Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2626cf6921Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2726cf6921Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2826cf6921Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2926cf6921Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3026cf6921Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3126cf6921Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3226cf6921Sthorpej * POSSIBILITY OF SUCH DAMAGE.
3326cf6921Sthorpej */
3426cf6921Sthorpej
3526cf6921Sthorpej #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
36*8ff6f65dSthorpej __KERNEL_RCSID(0, "$NetBSD: gapspci.c,v 1.22 2023/12/20 06:36:03 thorpej Exp $");
3726cf6921Sthorpej
3826cf6921Sthorpej #include <sys/param.h>
3926cf6921Sthorpej #include <sys/systm.h>
4026cf6921Sthorpej #include <sys/kernel.h>
4126cf6921Sthorpej #include <sys/device.h>
4226cf6921Sthorpej #include <sys/conf.h>
4326cf6921Sthorpej #include <sys/mbuf.h>
4486b5be6eSdyoung #include <sys/bus.h>
4526cf6921Sthorpej
4626cf6921Sthorpej #include <machine/cpu.h>
4726cf6921Sthorpej
4826cf6921Sthorpej #include <dev/pci/pcivar.h>
4926cf6921Sthorpej #include <dev/pci/pcireg.h>
5026cf6921Sthorpej
5126cf6921Sthorpej #include <dev/pci/pcidevs.h>
5226cf6921Sthorpej
5326cf6921Sthorpej #include <dreamcast/dev/g2/g2busvar.h>
5426cf6921Sthorpej #include <dreamcast/dev/g2/gapspcivar.h>
5526cf6921Sthorpej
56b1361f43Stsutsui int gaps_match(device_t, cfdata_t, void *);
57b1361f43Stsutsui void gaps_attach(device_t, device_t, void *);
5826cf6921Sthorpej
59b1361f43Stsutsui CFATTACH_DECL_NEW(gapspci, sizeof(struct gaps_softc),
60bd5bb465Sthorpej gaps_match, gaps_attach, NULL, NULL);
6126cf6921Sthorpej
6226cf6921Sthorpej int
gaps_match(device_t parent,cfdata_t cf,void * aux)63b1361f43Stsutsui gaps_match(device_t parent, cfdata_t cf, void *aux)
6426cf6921Sthorpej {
65fc7cc523Smarcus struct g2bus_attach_args *ga = aux;
66ae05e8edSmarcus uint8_t idbuf[16];
67fc7cc523Smarcus bus_space_handle_t tmp_memh;
6826cf6921Sthorpej
69fc7cc523Smarcus if (bus_space_map(ga->ga_memt, 0x01001400, 0x100, 0, &tmp_memh) != 0)
70fc7cc523Smarcus return 0;
71fc7cc523Smarcus
728dc36c4cStsutsui bus_space_read_region_1(ga->ga_memt, tmp_memh, 0, idbuf, sizeof(idbuf));
73fc7cc523Smarcus
74fc7cc523Smarcus bus_space_unmap(ga->ga_memt, tmp_memh, 0x100);
7526cf6921Sthorpej
76ae05e8edSmarcus if (strncmp((const char *)idbuf, "GAPSPCI_BRIDGE_2", 16))
7726cf6921Sthorpej return 0;
7826cf6921Sthorpej
79cb6453dbStsutsui return 1;
8026cf6921Sthorpej }
8126cf6921Sthorpej
8226cf6921Sthorpej void
gaps_attach(device_t parent,device_t self,void * aux)83b1361f43Stsutsui gaps_attach(device_t parent, device_t self, void *aux)
8426cf6921Sthorpej {
8526cf6921Sthorpej struct g2bus_attach_args *ga = aux;
86b1361f43Stsutsui struct gaps_softc *sc = device_private(self);
8726cf6921Sthorpej struct pcibus_attach_args pba;
8826cf6921Sthorpej int i;
8926cf6921Sthorpej
9026cf6921Sthorpej printf(": SEGA GAPS PCI Bridge\n");
9126cf6921Sthorpej
92b1361f43Stsutsui sc->sc_dev = self;
9326cf6921Sthorpej sc->sc_memt = ga->ga_memt;
9426cf6921Sthorpej
95fc7cc523Smarcus sc->sc_dmabase = 0x1840000;
96fc7cc523Smarcus sc->sc_dmasize = 32768;
97fc7cc523Smarcus
98fc7cc523Smarcus if (bus_space_map(sc->sc_memt, 0x01001400, 0x100,
99fc7cc523Smarcus 0, &sc->sc_gaps_memh) != 0)
100fc7cc523Smarcus panic("gaps_attach: can't map GAPS register space");
101fc7cc523Smarcus
102fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x18, 0x5a14a501);
10326cf6921Sthorpej
10426cf6921Sthorpej for (i = 0; i < 1000000; i++)
10526cf6921Sthorpej ;
10626cf6921Sthorpej
107fc7cc523Smarcus if (bus_space_read_4(sc->sc_memt, sc->sc_gaps_memh, 0x18) != 1)
108fc7cc523Smarcus panic("gaps_attach: GAPS PCI bridge not responding");
10926cf6921Sthorpej
110fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x20, 0x1000000);
111fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x24, 0x1000000);
112fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x28, sc->sc_dmabase);
113fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x2c,
114fc7cc523Smarcus sc->sc_dmabase + sc->sc_dmasize);
115fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x14, 1);
116fc7cc523Smarcus bus_space_write_4(sc->sc_memt, sc->sc_gaps_memh, 0x34, 1);
11726cf6921Sthorpej
11826cf6921Sthorpej gaps_pci_init(sc);
11926cf6921Sthorpej gaps_dma_init(sc);
12026cf6921Sthorpej
12126cf6921Sthorpej memset(&pba, 0, sizeof(pba));
12226cf6921Sthorpej
12326cf6921Sthorpej pba.pba_memt = sc->sc_memt;
12426cf6921Sthorpej pba.pba_dmat = &sc->sc_dmat;
1257dd7f8baSfvdl pba.pba_dmat64 = NULL;
12626cf6921Sthorpej pba.pba_bus = 0;
127204183c0Sthorpej pba.pba_bridgetag = NULL;
128a6b2b839Sdyoung pba.pba_flags = PCI_FLAGS_MEM_OKAY;
12926cf6921Sthorpej pba.pba_pc = &sc->sc_pc;
13026cf6921Sthorpej
131c7fb772bSthorpej config_found(self, &pba, pcibusprint, CFARGS_NONE);
13226cf6921Sthorpej }
133