1 /* $NetBSD: pchb.c,v 1.3 2004/08/30 15:05:18 drochner Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.3 2004/08/30 15:05:18 drochner Exp $"); 40 41 #include "pci.h" 42 #include "opt_pci.h" 43 44 #include <sys/types.h> 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/device.h> 48 #include <sys/extent.h> 49 #include <sys/malloc.h> 50 51 #define _IBM4XX_BUS_DMA_PRIVATE 52 53 #include <powerpc/ibm4xx/ibm405gp.h> 54 #include <powerpc/ibm4xx/dev/plbvar.h> 55 56 #include <dev/pci/pcivar.h> 57 #include <dev/pci/pcireg.h> 58 #include <dev/pci/pcidevs.h> 59 #include <dev/pci/pciconf.h> 60 61 static int pchbmatch(struct device *, struct cfdata *, void *); 62 static void pchbattach(struct device *, struct device *, void *); 63 static int pchbprint(void *, const char *); 64 65 CFATTACH_DECL(pchb, sizeof(struct device), 66 pchbmatch, pchbattach, NULL, NULL); 67 68 static int pcifound = 0; 69 70 /* IO window located @ e8000000 and maps to 0-0xffff */ 71 static struct powerpc_bus_space pchb_io_tag = { 72 _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_IO_TYPE, 73 IBM405GP_PLB_PCI_IO_START, /* offset */ 74 IBM405GP_PCI_PCI_IO_START, /* extent base */ 75 IBM405GP_PCI_PCI_IO_START + 0xffff, /* extent limit */ 76 }; 77 78 /* PCI memory window is directly mapped */ 79 static struct powerpc_bus_space pchb_mem_tag = { 80 _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_MEM_TYPE, 81 0x00000000, /* offset */ 82 IBM405GP_PCI_MEM_START, /* extent base */ 83 IBM405GP_PCI_MEM_START + 0x1fffffff, /* extent limit */ 84 }; 85 86 87 static int 88 pchbmatch(struct device *parent, struct cfdata *cf, void *aux) 89 { 90 struct plb_attach_args *paa = aux; 91 /* XXX chipset tag unused by walnut, so just pass 0 */ 92 pci_chipset_tag_t pc = 0; 93 pcitag_t tag; 94 int class, id; 95 96 /* match only pchb devices */ 97 if (strcmp(paa->plb_name, cf->cf_name) != 0) 98 return 0; 99 100 pci_machdep_init(); 101 tag = pci_make_tag(pc, 0, 0, 0); 102 103 class = pci_conf_read(pc, tag, PCI_CLASS_REG); 104 id = pci_conf_read(pc, tag, PCI_ID_REG); 105 106 /* 107 * Match all known PCI host chipsets. 108 */ 109 if (PCI_CLASS(class) == PCI_CLASS_BRIDGE && 110 PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_HOST) { 111 switch (PCI_VENDOR(id)) { 112 case PCI_VENDOR_IBM: 113 switch (PCI_PRODUCT(id)) { 114 case PCI_PRODUCT_IBM_405GP: 115 return (!pcifound); 116 } 117 break; 118 } 119 } 120 return (0); 121 } 122 123 static void 124 pchbattach(struct device *parent, struct device *self, void *aux) 125 { 126 struct plb_attach_args *paa = aux; 127 struct pcibus_attach_args pba; 128 char devinfo[256]; 129 #ifdef PCI_NETBSD_CONFIGURE 130 struct extent *ioext, *memext; 131 #ifdef PCI_CONFIGURE_VERBOSE 132 extern int pci_conf_debug; 133 134 pci_conf_debug = 1; 135 #endif 136 #endif 137 pci_chipset_tag_t pc = 0; 138 pcitag_t tag; 139 int class, id; 140 141 pci_machdep_init(); 142 tag = pci_make_tag(pc, 0, 0, 0); 143 144 class = pci_conf_read(pc, tag, PCI_CLASS_REG); 145 id = pci_conf_read(pc, tag, PCI_ID_REG); 146 147 printf("\n"); 148 pcifound++; 149 /* 150 * All we do is print out a description. Eventually, we 151 * might want to add code that does something that's 152 * possibly chipset-specific. 153 */ 154 155 pci_devinfo(id, class, 0, devinfo, sizeof(devinfo)); 156 printf("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo, 157 PCI_REVISION(class)); 158 159 pci_machdep_init(); /* Redundant... */ 160 ibm4xx_setup_pci(); 161 #ifdef PCI_CONFIGURE_VERBOSE 162 ibm4xx_show_pci_map(); 163 #endif 164 165 if (bus_space_init(&pchb_io_tag, "pchbio", NULL, 0)) 166 panic("pchbattach: can't init IO tag"); 167 if (bus_space_init(&pchb_mem_tag, "pchbmem", NULL, 0)) 168 panic("pchbattach: can't init MEM tag"); 169 170 #ifdef PCI_NETBSD_CONFIGURE 171 memext = extent_create("pcimem", IBM405GP_PCI_MEM_START, 172 IBM405GP_PCI_MEM_START + 0x1fffffff, M_DEVBUF, NULL, 0, 173 EX_NOWAIT); 174 ioext = extent_create("pciio", IBM405GP_PCI_PCI_IO_START, 175 IBM405GP_PCI_PCI_IO_START + 0xffff, M_DEVBUF, NULL, 0, EX_NOWAIT); 176 pci_configure_bus(0, ioext, memext, NULL, 0, 32); 177 extent_destroy(memext); 178 extent_destroy(ioext); 179 #endif /* PCI_NETBSD_CONFIGURE */ 180 181 #ifdef PCI_CONFIGURE_VERBOSE 182 printf("running config_found PCI\n"); 183 #endif 184 /* IO window located @ e8000000 and maps to 0-0xffff */ 185 pba.pba_iot = &pchb_io_tag; 186 /* PCI memory window is directly mapped */ 187 pba.pba_memt = &pchb_mem_tag; 188 pba.pba_dmat = paa->plb_dmat; 189 pba.pba_dmat64 = NULL; 190 pba.pba_bus = 0; 191 pba.pba_bridgetag = NULL; 192 pba.pba_flags = PCI_FLAGS_MEM_ENABLED | PCI_FLAGS_IO_ENABLED; 193 config_found_ia(self, "pcibus", &pba, pchbprint); 194 } 195 196 197 static int 198 pchbprint(void *aux, const char *p) 199 { 200 201 if (p == NULL) 202 return (UNCONF); 203 return (QUIET); 204 } 205 206 #if 0 207 static void 208 scan_pci_bus(void) 209 { 210 pcitag_t tag; 211 int i, x; 212 213 for (i=0;i<32;i++){ 214 tag = pci_make_tag(0, 0, i, 0); 215 x = pci_conf_read(0, tag, 0); 216 printf("%d tag=%08x : %08x\n", i, tag, x); 217 #if 0 218 if (PCI_VENDOR(x) == PCI_VENDOR_INTEL 219 && PCI_PRODUCT(x) == PCI_PRODUCT_INTEL_80960_RP) { 220 /* Do not configure PCI bus analyzer */ 221 continue; 222 } 223 x = pci_conf_read(0, tag, PCI_COMMAND_STATUS_REG); 224 x |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; 225 pci_conf_write(0, tag, PCI_COMMAND_STATUS_REG, x); 226 #endif 227 } 228 } 229 #endif 230