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