1 /* $NetBSD: gt_mainbus.c,v 1.13 2006/02/10 20:52:57 gdamore Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Allen Briggs for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: gt_mainbus.c,v 1.13 2006/02/10 20:52:57 gdamore Exp $"); 40 41 #include "opt_ev64260.h" 42 43 #include <sys/types.h> 44 #include <sys/param.h> 45 #include <sys/device.h> 46 #include <sys/extent.h> 47 #include <sys/malloc.h> 48 49 #define _POWERPC_BUS_DMA_PRIVATE 50 #include <machine/bus.h> 51 52 #include "opt_pci.h" 53 #include <dev/pci/pcivar.h> 54 #include <dev/pci/pciconf.h> 55 56 #include "opt_marvell.h" 57 #include <dev/marvell/gtreg.h> 58 #include <dev/marvell/gtvar.h> 59 #include <dev/marvell/gtpcireg.h> 60 #include <dev/marvell/gtpcivar.h> 61 62 extern struct powerpc_bus_space gt_mem_bs_tag; 63 extern struct powerpc_bus_space gt_pci0_mem_bs_tag; 64 extern struct powerpc_bus_space gt_pci0_io_bs_tag; 65 extern struct powerpc_bus_space gt_pci1_mem_bs_tag; 66 extern struct powerpc_bus_space gt_pci1_io_bs_tag; 67 68 struct powerpc_bus_dma_tag gt_bus_dma_tag = { 69 0, /* _bounce_thresh */ 70 _bus_dmamap_create, 71 _bus_dmamap_destroy, 72 _bus_dmamap_load, 73 _bus_dmamap_load_mbuf, 74 _bus_dmamap_load_uio, 75 _bus_dmamap_load_raw, 76 _bus_dmamap_unload, 77 _bus_dmamap_sync, 78 _bus_dmamem_alloc, 79 _bus_dmamem_free, 80 _bus_dmamem_map, 81 _bus_dmamem_unmap, 82 _bus_dmamem_mmap, 83 gt_dma_phys_to_bus_mem, 84 gt_dma_bus_mem_to_phys, 85 }; 86 87 const int gtpci_skipmask[2] = { 88 #ifdef PCI0_SKIPMASK 89 PCI0_SKIPMASK, 90 #else 91 0, 92 #endif 93 #ifdef PCI1_SKIPMASK 94 PCI1_SKIPMASK, 95 #else 96 0, 97 #endif 98 }; 99 100 static int gt_match(struct device *, struct cfdata *, void *); 101 static void gt_attach(struct device *, struct device *, void *); 102 103 CFATTACH_DECL(gt, sizeof(struct gt_softc), gt_match, gt_attach, NULL, NULL); 104 105 extern struct cfdriver gt_cd; 106 extern bus_space_handle_t gt_memh; 107 108 static int gt_found; 109 110 int 111 gt_match(struct device *parent, struct cfdata *cf, void *aux) 112 { 113 const char **busname = aux; 114 115 if (strcmp(*busname, gt_cd.cd_name) != 0) 116 return 0; 117 118 if (gt_found) 119 return 0; 120 121 return 1; 122 } 123 124 void 125 gt_attach(struct device *parent, struct device *self, void *aux) 126 { 127 struct gt_softc *gt = (struct gt_softc *) self; 128 129 gt->gt_dmat = >_bus_dma_tag; 130 gt->gt_memt = >_mem_bs_tag; 131 gt->gt_pci0_memt = >_pci0_mem_bs_tag; 132 gt->gt_pci0_iot = >_pci0_io_bs_tag; 133 gt->gt_pci0_host = TRUE; 134 gt->gt_pci1_memt = >_pci1_mem_bs_tag; 135 gt->gt_pci1_iot = >_pci1_io_bs_tag; 136 gt->gt_pci1_host = TRUE; 137 138 gt->gt_memh = gt_memh; 139 140 #if 0 141 GT_DecodeAddr_SET(gt, GT_PCI0_IO_Low_Decode, 142 gt_pci0_io_bs_tag.pbs_offset + gt_pci0_io_bs_tag.pbs_base); 143 GT_DecodeAddr_SET(gt, GT_PCI0_IO_High_Decode, 144 gt_pci0_io_bs_tag.pbs_offset + gt_pci0_io_bs_tag.pbs_limit - 1); 145 146 GT_DecodeAddr_SET(gt, GT_PCI1_IO_Low_Decode, 147 gt_pci1_io_bs_tag.pbs_offset + gt_pci1_io_bs_tag.pbs_base); 148 GT_DecodeAddr_SET(gt, GT_PCI1_IO_High_Decode, 149 gt_pci1_io_bs_tag.pbs_offset + gt_pci1_io_bs_tag.pbs_limit - 1); 150 151 GT_DecodeAddr_SET(gt, GT_PCI0_Mem0_Low_Decode, 152 gt_pci0_mem_bs_tag.pbs_offset + gt_pci0_mem_bs_tag.pbs_base); 153 GT_DecodeAddr_SET(gt, GT_PCI0_Mem0_High_Decode, 154 gt_pci1_mem_bs_tag.pbs_offset + gt_pci1_mem_bs_tag.pbs_limit - 1); 155 156 GT_DecodeAddr_SET(gt, GT_PCI1_Mem0_Low_Decode, 157 gt_pci1_mem_bs_tag.pbs_offset + gt_pci1_mem_bs_tag.pbs_base); 158 GT_DecodeAddr_SET(gt, GT_PCI1_Mem0_High_Decode, 159 gt_pci1_mem_bs_tag.pbs_offset + gt_pci1_mem_bs_tag.pbs_limit - 1); 160 #endif 161 162 gt_attach_common(gt); 163 } 164 165 void 166 gtpci_bus_configure(struct gtpci_chipset *gtpc) 167 { 168 #ifdef PCI_NETBSD_CONFIGURE 169 struct extent *ioext, *memext; 170 #if 0 171 extern int pci_conf_debug; 172 pci_conf_debug = 1; 173 #endif 174 175 switch (gtpc->gtpc_busno) { 176 case 0: 177 ioext = extent_create("pci0-io", 0x00000600, 0x0000ffff, 178 M_DEVBUF, NULL, 0, EX_NOWAIT); 179 memext = extent_create("pci0-mem", 180 gt_pci0_mem_bs_tag.pbs_base, 181 gt_pci0_mem_bs_tag.pbs_limit-1, 182 M_DEVBUF, NULL, 0, EX_NOWAIT); 183 break; 184 case 1: 185 ioext = extent_create("pci1-io", 0x00000600, 0x0000ffff, 186 M_DEVBUF, NULL, 0, EX_NOWAIT); 187 memext = extent_create("pci1-mem", 188 gt_pci1_mem_bs_tag.pbs_base, 189 gt_pci1_mem_bs_tag.pbs_limit-1, 190 M_DEVBUF, NULL, 0, EX_NOWAIT); 191 break; 192 default: 193 panic("gtpci_bus_configure: unknown bus %d", gtpc->gtpc_busno); 194 } 195 196 pci_configure_bus(>pc->gtpc_pc, ioext, memext, NULL, 0, 32); 197 198 extent_destroy(ioext); 199 extent_destroy(memext); 200 #endif /* PCI_NETBSD_CONFIGURE */ 201 } 202 203 void 204 gtpci_md_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin, 205 int swiz, int *iline) 206 { 207 #ifdef PCI_NETBSD_CONFIGURE 208 struct gtpci_chipset *gtpc = (struct gtpci_chipset *)pc; 209 int line = (gtpc->gtpc_busno == 0 ? PCI0_GPPINTS : PCI1_GPPINTS); 210 *iline = (line >> (8 * ((pin + swiz - 1) & 3))) & 0xff; 211 if (*iline != 0xff) 212 *iline += IRQ_GPP_BASE; 213 #endif /* PCI_NETBSD_CONFIGURE */ 214 } 215 216 void 217 gtpci_md_bus_devorder(pci_chipset_tag_t pc, int busno, char devs[]) 218 { 219 struct gtpci_chipset *gtpc = (struct gtpci_chipset *)pc; 220 int dev; 221 222 /* 223 * Don't bother probing the GT itself. 224 */ 225 for (dev = 0; dev < 32; dev++) { 226 if (PCI_CFG_GET_BUSNO(gtpc->gtpc_self) == busno && 227 (PCI_CFG_GET_DEVNO(gtpc->gtpc_self) == dev || 228 (gtpci_skipmask[gtpc->gtpc_busno] & (1 << dev)))) 229 continue; 230 231 *devs++ = dev; 232 } 233 *devs = -1; 234 } 235 236 int 237 gtpci_md_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, 238 pcireg_t id) 239 { 240 if (bus == 0 && dev == 0) /* don't configure GT */ 241 return 0; 242 243 return PCI_CONF_DEFAULT; 244 } 245 246 int 247 gtpci_md_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 248 { 249 int pin = pa->pa_intrpin; 250 int line = pa->pa_intrline; 251 252 if (pin > 4 || line >= NIRQ) { 253 printf("pci_intr_map: bad interrupt pin %d\n", pin); 254 *ihp = -1; 255 return 1; 256 } 257 258 *ihp = line; 259 return 0; 260 } 261