xref: /netbsd-src/sys/arch/powerpc/ibm4xx/pci/pchb.c (revision e5fbc36ada28f9b9a5836ecffaf4a06aa1ebb687)
1*e5fbc36aSthorpej /*	$NetBSD: pchb.c,v 1.17 2023/12/20 15:29:06 thorpej Exp $	*/
2dc98452dSshige 
3dc98452dSshige /*-
4dc98452dSshige  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5dc98452dSshige  * All rights reserved.
6dc98452dSshige  *
7dc98452dSshige  * This code is derived from software contributed to The NetBSD Foundation
8dc98452dSshige  * by Jason R. Thorpe.
9dc98452dSshige  *
10dc98452dSshige  * Redistribution and use in source and binary forms, with or without
11dc98452dSshige  * modification, are permitted provided that the following conditions
12dc98452dSshige  * are met:
13dc98452dSshige  * 1. Redistributions of source code must retain the above copyright
14dc98452dSshige  *    notice, this list of conditions and the following disclaimer.
15dc98452dSshige  * 2. Redistributions in binary form must reproduce the above copyright
16dc98452dSshige  *    notice, this list of conditions and the following disclaimer in the
17dc98452dSshige  *    documentation and/or other materials provided with the distribution.
18dc98452dSshige  *
19dc98452dSshige  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20dc98452dSshige  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21dc98452dSshige  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223b9bf494Smartin  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
233b9bf494Smartin  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24dc98452dSshige  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25dc98452dSshige  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26dc98452dSshige  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27dc98452dSshige  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28dc98452dSshige  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29dc98452dSshige  * POSSIBILITY OF SUCH DAMAGE.
30dc98452dSshige  */
3116031f7dSrin 
32dc98452dSshige #include <sys/cdefs.h>
33*e5fbc36aSthorpej __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.17 2023/12/20 15:29:06 thorpej Exp $");
34dc98452dSshige 
35dc98452dSshige #include "pci.h"
3616031f7dSrin 
3716031f7dSrin #ifdef _KERNEL_OPT
38dc98452dSshige #include "opt_pci.h"
3916031f7dSrin #endif
40dc98452dSshige 
41dc98452dSshige #include <sys/types.h>
42dc98452dSshige #include <sys/param.h>
43dc98452dSshige #include <sys/systm.h>
44dc98452dSshige #include <sys/device.h>
45dc98452dSshige 
46dc98452dSshige #define _IBM4XX_BUS_DMA_PRIVATE
47dc98452dSshige 
48dc98452dSshige #include <powerpc/ibm4xx/ibm405gp.h>
49dd2488a8Smatt #include <powerpc/ibm4xx/pci_machdep.h>
50dc98452dSshige #include <powerpc/ibm4xx/dev/plbvar.h>
51dc98452dSshige 
52dc98452dSshige #include <dev/pci/pcivar.h>
53dc98452dSshige #include <dev/pci/pcireg.h>
54dc98452dSshige #include <dev/pci/pcidevs.h>
55dc98452dSshige #include <dev/pci/pciconf.h>
56dc98452dSshige 
57ec1797c1Smatt static int	pchbmatch(device_t, cfdata_t, void *);
58ec1797c1Smatt static void	pchbattach(device_t, device_t, void *);
59dc98452dSshige static int	pchbprint(void *, const char *);
60dc98452dSshige 
61ec1797c1Smatt CFATTACH_DECL_NEW(pchb, 0,
62dc98452dSshige     pchbmatch, pchbattach, NULL, NULL);
63dc98452dSshige 
64dc98452dSshige static int pcifound = 0;
65dc98452dSshige 
66dc98452dSshige /* IO window located @ e8000000 and maps to 0-0xffff */
67dc98452dSshige static struct powerpc_bus_space pchb_io_tag = {
68dc98452dSshige 	_BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_IO_TYPE,
69dc98452dSshige 	IBM405GP_PLB_PCI_IO_START,		/* offset */
70dc98452dSshige 	IBM405GP_PCI_PCI_IO_START,		/* extent base */
71dc98452dSshige 	IBM405GP_PCI_PCI_IO_START + 0xffff,	/* extent limit */
72dc98452dSshige };
73dc98452dSshige 
74dc98452dSshige /* PCI memory window is directly mapped */
75dc98452dSshige static struct powerpc_bus_space pchb_mem_tag = {
76dc98452dSshige 	_BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_MEM_TYPE,
77dc98452dSshige 	0x00000000,					/* offset */
78dc98452dSshige 	IBM405GP_PCI_MEM_START,			/* extent base */
79dc98452dSshige 	IBM405GP_PCI_MEM_START + 0x1fffffff,	/* extent limit */
80dc98452dSshige };
81dc98452dSshige 
82dc98452dSshige 
83dc98452dSshige static int
pchbmatch(device_t parent,cfdata_t cf,void * aux)84ec1797c1Smatt pchbmatch(device_t parent, cfdata_t cf, void *aux)
85dc98452dSshige {
86dc98452dSshige 	struct plb_attach_args *paa = aux;
87dc98452dSshige 	/* XXX chipset tag unused by walnut, so just pass 0 */
88dd2488a8Smatt 	pci_chipset_tag_t pc = ibm4xx_get_pci_chipset_tag();
89dc98452dSshige 	pcitag_t tag;
90dc98452dSshige 	int class, id;
91dc98452dSshige 
92dc98452dSshige 	/* match only pchb devices */
93dc98452dSshige 	if (strcmp(paa->plb_name, cf->cf_name) != 0)
94dc98452dSshige 		return 0;
95dc98452dSshige 
96dd2488a8Smatt 	ibm4xx_pci_machdep_init();
97dc98452dSshige 	tag = pci_make_tag(pc, 0, 0, 0);
98dc98452dSshige 
99dc98452dSshige 	class = pci_conf_read(pc, tag, PCI_CLASS_REG);
100dc98452dSshige 	id = pci_conf_read(pc, tag, PCI_ID_REG);
101dc98452dSshige 
102dc98452dSshige 	/*
103dc98452dSshige 	 * Match all known PCI host chipsets.
104dc98452dSshige 	 */
105dc98452dSshige 	if (PCI_CLASS(class) == PCI_CLASS_BRIDGE &&
106dc98452dSshige 	    PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_HOST) {
107dc98452dSshige 		switch (PCI_VENDOR(id)) {
108dc98452dSshige 		case PCI_VENDOR_IBM:
109dc98452dSshige 			switch (PCI_PRODUCT(id)) {
110dc98452dSshige 			case PCI_PRODUCT_IBM_405GP:
111dc98452dSshige 				return (!pcifound);
112dc98452dSshige 			}
113dc98452dSshige 			break;
114dc98452dSshige 		}
115dc98452dSshige 	}
116dc98452dSshige 	return (0);
117dc98452dSshige }
118dc98452dSshige 
119dc98452dSshige static void
pchbattach(device_t parent,device_t self,void * aux)120ec1797c1Smatt pchbattach(device_t parent, device_t self, void *aux)
121dc98452dSshige {
122dc98452dSshige 	struct plb_attach_args *paa = aux;
123dc98452dSshige 	struct pcibus_attach_args pba;
124dc98452dSshige 	char devinfo[256];
125dc98452dSshige #ifdef PCI_CONFIGURE_VERBOSE
126dc98452dSshige 	extern int pci_conf_debug;
127dc98452dSshige 
128dc98452dSshige 	pci_conf_debug = 1;
129dc98452dSshige #endif
130dd2488a8Smatt 	pci_chipset_tag_t pc = ibm4xx_get_pci_chipset_tag();
131dc98452dSshige 	pcitag_t tag;
132dc98452dSshige 	int class, id;
133dc98452dSshige 
134dd2488a8Smatt 	ibm4xx_pci_machdep_init();
135dc98452dSshige 	tag = pci_make_tag(pc, 0, 0, 0);
136dc98452dSshige 
137dc98452dSshige 	class = pci_conf_read(pc, tag, PCI_CLASS_REG);
138dc98452dSshige 	id = pci_conf_read(pc, tag, PCI_ID_REG);
139dc98452dSshige 
140036ca983Smatt 	aprint_normal("\n");
141dc98452dSshige 	pcifound++;
142dc98452dSshige 	/*
143dc98452dSshige 	 * All we do is print out a description.  Eventually, we
144dc98452dSshige 	 * might want to add code that does something that's
145dc98452dSshige 	 * possibly chipset-specific.
146dc98452dSshige 	 */
147dc98452dSshige 
1480e5d2423Skleink 	pci_devinfo(id, class, 0, devinfo, sizeof(devinfo));
149036ca983Smatt 	aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo,
150dc98452dSshige 	    PCI_REVISION(class));
151dc98452dSshige 
152dd2488a8Smatt 	ibm4xx_pci_machdep_init(); /* Redundant... */
153dc98452dSshige 	ibm4xx_setup_pci();
154dc98452dSshige #ifdef PCI_CONFIGURE_VERBOSE
155dc98452dSshige 	ibm4xx_show_pci_map();
156dc98452dSshige #endif
157dc98452dSshige 
158dc98452dSshige 	if (bus_space_init(&pchb_io_tag, "pchbio", NULL, 0))
159dc98452dSshige 		panic("pchbattach: can't init IO tag");
160dc98452dSshige 	if (bus_space_init(&pchb_mem_tag, "pchbmem", NULL, 0))
161dc98452dSshige 		panic("pchbattach: can't init MEM tag");
162dc98452dSshige 
163dc98452dSshige #ifdef PCI_NETBSD_CONFIGURE
164ca8ce3aeSthorpej 	struct pciconf_resources *pcires = pciconf_resource_init();
165ca8ce3aeSthorpej 
166ca8ce3aeSthorpej 	pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
167ca8ce3aeSthorpej 	    IBM405GP_PCI_PCI_IO_START, 0x10000);
168ca8ce3aeSthorpej 	pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
169ca8ce3aeSthorpej 	    IBM405GP_PCI_MEM_START, 0x20000000);
170ca8ce3aeSthorpej 
171ca8ce3aeSthorpej 	pci_configure_bus(pc, pcires, 0, 32);
172ca8ce3aeSthorpej 	pciconf_resource_fini(pcires);
173dc98452dSshige #endif /* PCI_NETBSD_CONFIGURE */
174dc98452dSshige 
175dc98452dSshige #ifdef PCI_CONFIGURE_VERBOSE
176dc98452dSshige 	printf("running config_found PCI\n");
177dc98452dSshige #endif
178dc98452dSshige 	/* IO window located @ e8000000 and maps to 0-0xffff */
179dc98452dSshige 	pba.pba_iot = &pchb_io_tag;
180dc98452dSshige 	/* PCI memory window is directly mapped */
181dc98452dSshige 	pba.pba_memt = &pchb_mem_tag;
182dc98452dSshige 	pba.pba_dmat = paa->plb_dmat;
183dc98452dSshige 	pba.pba_dmat64 = NULL;
184db37c957Skiyohara 	pba.pba_pc = pc;
185dc98452dSshige 	pba.pba_bus = 0;
186dc98452dSshige 	pba.pba_bridgetag = NULL;
187a6b2b839Sdyoung 	pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY;
188c7fb772bSthorpej 	config_found(self, &pba, pchbprint, CFARGS_NONE);
189dc98452dSshige }
190dc98452dSshige 
191dc98452dSshige 
192dc98452dSshige static int
pchbprint(void * aux,const char * p)193dc98452dSshige pchbprint(void *aux, const char *p)
194dc98452dSshige {
195dc98452dSshige 
196dc98452dSshige 	if (p == NULL)
197dc98452dSshige 		return (UNCONF);
198dc98452dSshige 	return (QUIET);
199dc98452dSshige }
200dc98452dSshige 
201dc98452dSshige #if 0
202dc98452dSshige static void
203dc98452dSshige scan_pci_bus(void)
204dc98452dSshige {
205dd2488a8Smatt 	pci_chipset_tag_t pc = ibm4xx_get_pci_chipset_tag();
206dc98452dSshige 	pcitag_t tag;
207dc98452dSshige 	int i, x;
208dc98452dSshige 
209dc98452dSshige 	for (i=0;i<32;i++){
210dd2488a8Smatt 		tag = pci_make_tag(pc, 0, i, 0);
211dd2488a8Smatt 		x = pci_conf_read(pc, tag, 0);
212dc98452dSshige 		printf("%d tag=%08x : %08x\n", i, tag, x);
213dc98452dSshige #if 0
214dc98452dSshige 		if (PCI_VENDOR(x) == PCI_VENDOR_INTEL
215dc98452dSshige 		    && PCI_PRODUCT(x) == PCI_PRODUCT_INTEL_80960_RP) {
216dc98452dSshige 			/* Do not configure PCI bus analyzer */
217dc98452dSshige 			continue;
218dc98452dSshige 		}
219dd2488a8Smatt 		x = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
220dc98452dSshige 		x |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
221dc98452dSshige 		pci_conf_write(0, tag, PCI_COMMAND_STATUS_REG, x);
222dc98452dSshige #endif
223dc98452dSshige 	}
224dc98452dSshige }
225dc98452dSshige #endif
226